启用僵尸对象不足以帮助调试我的问题 - 我还能做啥?
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:animated
或pushViewController: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...这可能是来自调试器的虚假消息吗?以上是关于启用僵尸对象不足以帮助调试我的问题 - 我还能做啥?的主要内容,如果未能解决你的问题,请参考以下文章
当 sleep() 不能很好地与警报一起工作时,我还能做啥“睡眠”?
引入 git switch 后 git checkout 还能做啥?