在传递有效对象时EXC_BAD_ACCESS

时间:2011-08-31 18:30:37

标签: objective-c ios exc-bad-access ipad-2

我的主应用控制器调用子控制器来处理特定的屏幕序列。主控制器将自身设置为子控制器中的委托。当子控制器完成其内容时,它会通知代理。时不时地,此通知因EXC_BAD_ACCESS而失败。

0)基于gdb,问题出现在objc_msgSend中。两个寄存器都具有非零值。

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

1)我已经尝试过NSZombiesEnabled来跟踪问题,但我无法重现它。 2)我已经尝试在有问题的命令之前设置断点,但我再次无法重现该问题。

我不知道发生了什么。

这是委托属性声明(父控制器比子节点更长):

@property (assign) id<ParentControllerDelegate> delegate

这是有问题的代码:

- (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
}

这是委托方面的代码(委托已由App_Delegate保留,因为它是主控制器)。

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

一些额外信息: 主控制器保留子控制器。 我还修改了主控制器和子控制器中的deallocs,以便在调用它时进行记录。基于可见日志,在应用程序的过程中都没有调用过。因此,消息的接收者和发送者都是有效的对象。

我真的很茫然。期待您的帮助。

3 个答案:

答案 0 :(得分:0)

只是一个疯狂的猜测,但如果它是“偶然”,则可能viewDidLoadviewDidUnload在收到内存警告后导致EXC_BAD_ACCESS。检查父/子控制器中已发布/保留/创建的实例变量,尤其是前面提到的视图加载方法。

答案 1 :(得分:0)

如果NSLog中的done:来电从未执行过,那只能表示您没有调用主控制器的done:。这可能意味着self.delegate无效。对象可能有效且有效,但不是它们之间的链接(self.delegate)。请检查一下。在doStuff,在“完成”分支中,使用

显示self.delegate的地址
NSLog(@"%p", self.delegate);

在致电done:并将其与主控制器的地址进行比较之前。

答案 2 :(得分:0)

尝试在调用之前执行检查协议和方法,如代码所示:

- (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