启用僵尸对象不足以帮助调试我的问题 - 我还能做啥?

Posted

技术标签:

【中文标题】启用僵尸对象不足以帮助调试我的问题 - 我还能做啥?【英文标题】:Enable Zombie Objects is not enough to help debug my issue - what else can I do?启用僵尸对象不足以帮助调试我的问题 - 我还能做什么? 【发布时间】:2012-06-18 01:47:30 【问题描述】:

我收到以下运行时错误,我无法确定我的一生 WHYYYY。错误是Thread 1: EXC_BREAKPOINT (code=EXC_1386_BPT, subcode=0x0),每当我从我的任何VC 执行dismissModalViewController:animatedpushViewController:animated 方法时,似乎都会发生这种错误。

我启用了僵尸对象,并在调试器中显示以下消息,2012-06-14 16:34:58.769 MyApp[5952:17903] *** -[MyDetailsVC respondsToSelector:]: message sent to deallocated instance 0x8c3d400

发生在我访问 MyDetailsVC ViewController 之后。场景如下。

启动应用程序,一切正常,我可以推送到视图控制器并从视图控制器弹出,并呈现和关闭模态 VC,没有任何问题。 我推到 MyDetailsVC,在它上面什么都不做,然后点击返回按钮。 我现在回到了推送到 MyDetailsVC 之前的位置,该应用程序继续完美运行,直到我必须推送到 VC 或呈现模态 VC。然后我得到运行时错误。

当我遇到错误时,MyDetailsVC 甚至不在图片中,也与其他 VC 没有任何关系。

我怎样才能更详细地使用调试器来确定这个问题是什么?

此外,错误消息说“消息已发送”,所以我几乎在我的 VC 中评论了我所有的 NSNotifications,以排除我的一个 VC 试图向 VC 发送消息的可能性不再活着...没有运气!

PS - 我正在使用 Xcode 4.3.1、5.1 w/ARC

【问题讨论】:

【参考方案1】:

调试器的回调堆栈中没有任何内容可以显示代码的哪一行正在发生?

respondsToSelector 在委托上被大量调用(以查看是否实现了协议中的可选方法)。您的 MyDetailsVC 是否将自己指定为任何事情的代表?如果是这样,请务必在您的 dealloc 例程中分配 xyz.delegate = nil。

所以你可能有“self.navigationController.delegate = self”。因此,您需要在您的 dealloc 例程中匹配“self.navigationController.delegate = nil”。

【讨论】:

不,我没有将它分配给任何东西,但是我确实在其中使用了以下协议。 (<UITableViewDataSource, UITableViewDelegate, NSURLConnectionDelegate, UIActionSheetDelegate, UIAlertViewDelegate, UINavigationControllerDelegate>)。在调试器的回调堆栈中,它始终指向在任何使用该方法的 VC 中读取 [self dismissModalViewControllerAnimated:YES]; 的代码行,并且对 [self.navigationController pushViewController:someOtherVC animated:YES]; 执行相同操作 所以,你被分配为所有这些事情的代表,不是吗? (例如 self.tableview.delegate = self )所有这些都需要在您的 dealloc 期间被取消(尽管您的 tableview 本身应该被释放。就个人而言,我会查看 UINavController 委托,因为您的 myDetailsVC 会收到通知通过您的模态/推送呼叫。 天啊,[self.navigationController setDelegate:self]; 是问题所在!我从标题中删除了协议,并注释掉了 setDelegate:self 行,viola 成功了!非常感谢你的帮助!!请提交您的评论作为答案,我会将其标记为已接受。 那么我应该把setDelegate:nil 调用放在哪里呢?我的 viewDidUnload 仅在应用收到内存警告并且 VC 不在视图中时才会被调用。我应该把它放在- (void)dealloc [self.navigationController setDelegate:nil]; 吗?我试过了,但它不能解决问题。 这就是它应该去的地方(尽管我 viewDidUnload 也应该工作;很确定这是在 VC 的 dealloc 之前调用的)。我不知道你为什么需要回调,但如果它只是当你在屏幕上时,那么你可以在 viewDidDisappear 中将它设置为 nil。【参考方案2】:

问题不在于 NSNotifications。 Objective-c 中的消息只是函数/方法调用。看起来 respondsToSelector: 是导致问题的原因。

检查 MyDetailsVC 是否有 [self respondsToSelector:@"some method here"]。也可能是在 MyDetailsVC 被解除和释放后,另一个对象在 MyDetailsVC 上调用了 respondsToSelector。确保在 MyDetailsVC 中 viewDidUnload 下将 @synthesized 属性设置为 nil 并停止所有待处理的 performSelector 调用。

【讨论】:

我在 MyDetailsVC 中搜索了任何使用 @selector 的东西,我发现的所有 (6) 个方法都是仅在 MyDetailsVC 中使用的稀有方法。例如,执行小任务的按钮上的选择器、显示 actionSheets 等......另外,在我的 ViewDidLoad 方法中,我在第一行有一条 NSLog 消息,以查看 ViewDidLoad 是否曾经被调用过,但它从来没有这样我不'甚至都不知道如何释放 MyDetailsVC...这可能是来自调试器的虚假消息吗?

以上是关于启用僵尸对象不足以帮助调试我的问题 - 我还能做啥?的主要内容,如果未能解决你的问题,请参考以下文章

除了多个 if 语句,我还能做啥? PHP 注册脚本

当 sleep() 不能很好地与警报一起工作时,我还能做啥“睡眠”?

引入 git switch 后 git checkout 还能做啥?

在 ARM Cortex-A8 上启用 MMU 时出现问题。 CPU是S5PV210

用"僵尸对象"调试内存管理问题

我还能提高 GPS 精度吗?