开发者

EXC_BAD_ACCESS when messaging a valid object

My main app controller invokes a subcontroller to handle a certain sequence of screens. The main controller sets itself as a delegate in the subcontroller. When the subcontroller is done doing its stuff, it notifies the delegate. Every now and then, this notification fails with EXC_BAD_ACCESS.

0)Based on gdb, the problem occurs in objc_msgSend. Both registers have a non-zero value.

gdb: 0x3367cc98  <+0016>  ldr   r5, [r4, #8]

1)I've tried NSZombiesEnabled to track the problem, but I couldn't reproduce it then. 2)I've tried setting a breakpoint just before the problematic command, but again I can't reproduce the issue.

I have no clue what's going on.

This is the delegate property declaration (the parent controller outlives the child):

@property (assign) id<ParentControllerDelegate> delegate

This is the problematic code:

- (void) doStuff {
   if(mode == Done) {
     NSLog(@"Done. Handling back control");//this开发者_运维知识库 is the last log displayed by the console
     [self.delegate done: self];
   } else {
     // some controller code
}

This is the the code on the delegate side (the delegate has been retained by the App_Delegate, as it is the main controller).

- (void) done: (UIViewController *) caller {
   NSLog(@"Taken back control");// this never displays
   [caller.view removeFromSuperview];
   [caller release];
}

Some extra info: The main controller retains the subcontroller. I've also modified the deallocs in both the main and sub controllers to log when it is called. Based on the visible logs, neither is ever called during the course of the application. Hence both the receiver and the sender of the message are valid objects.

I'm really at loss here. Looking forward to your help.


If the NSLog call in done: is never performed, that can only mean that you did not call the main controller's done:. That can mean that self.delegate is not valid. The objects may be valid and alive, but not the link (self.delegate) between them. Check that, please. In doStuff, in the "Done" branch, show the address of self.delegate with

NSLog(@"%p", self.delegate);

before you call done: and compare that with the address of the main controller.


Just a wild guess, but if it's "now and then" it's probably viewDidLoad or viewDidUnload causing the EXC_BAD_ACCESS after receiving memory warning. Check your released/retained/created instance variables in your parent/child controller especially in aforementioned view loading methods.


Try to perform check protocol and method before call as in the code:

- (void) doStuff 
{
    if(mode == Done) 
    {
        NSLog(@"Done. Handling back control");//this is the last log displayed by the console
        if ([delegate conformsToProtocol: @protocol(ParentControllerDelegate)])
        {
            if ([delegate respondsToSelector: @selector(done:)] == YES)
            {
                [delegate performSelector: @selector(done:) withObject: self];            
            }
        }
    } 
    else 
    {
       // some controller code
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜