我的主应用控制器调用子控制器来处理特定的屏幕序列。主控制器将自身设置为子控制器中的委托。当子控制器完成其内容时,它会通知代理。时不时地,此通知因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,以便在调用它时进行记录。基于可见日志,在应用程序的过程中都没有调用过。因此,消息的接收者和发送者都是有效的对象。
我真的很茫然。期待您的帮助。
答案 0 :(得分:0)
只是一个疯狂的猜测,但如果它是“偶然”,则可能viewDidLoad
或viewDidUnload
在收到内存警告后导致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