向有效对象发送消息时的 EXC_BAD_ACCESS
我的主应用程序控制器调用子控制器来处理特定的屏幕序列。主控制器将自己设置为子控制器中的委托。当子控制器完成其工作时,它会通知委托人。有时,此通知会失败并显示 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];
}
一些额外的信息: 主控制器保留子控制器。 我还修改了主控制器和子控制器中的释放以在调用时进行记录。根据可见日志,在应用程序过程中都不会调用这两个方法。因此消息的接收者和发送者都是有效的对象。
我真的很茫然。期待您的帮助。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果
done:
中的NSLog
调用从未执行过,那只能意味着您没有调用主控制器的done:
。这可能意味着 self.delegate 无效。这些对象可能是有效且活动的,但它们之间的链接 (self.delegate
) 不是。请检查一下。 显示self.delegate
的地址在
doStuff
的“Done”分支中,在调用done:
之前 ,并将其与该地址进行比较主控制器的。If the
NSLog
call indone:
is never performed, that can only mean that you did not call the main controller'sdone:
. That can mean thatself.delegate
is not valid. The objects may be valid and alive, but not the link (self.delegate
) between them. Check that, please. IndoStuff
, in the "Done" branch, show the address ofself.delegate
withbefore you call
done:
and compare that with the address of the main controller.只是一个大胆的猜测,但如果是“偶尔”,则可能是
viewDidLoad
或viewDidUnload
在收到内存警告后导致EXC_BAD_ACCESS
。检查父/子控制器中释放/保留/创建的实例变量,尤其是在上述视图加载方法中。Just a wild guess, but if it's "now and then" it's probably
viewDidLoad
orviewDidUnload
causing theEXC_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: