SEGV_ACCERR在dealloc中调用[[NSNotificationCenter defaultCenter] removeObserver:self] [英] SEGV_ACCERR calling [[NSNotificationCenter defaultCenter] removeObserver:self] in dealloc

查看:1996
本文介绍了SEGV_ACCERR在dealloc中调用[[NSNotificationCenter defaultCenter] removeObserver:self]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的不知道这是怎么发生的。我有一个使用ARC的应用程序。我的大多数视图控制器都注册了NSNotifications。所有注册都在主线程上完成。

I'm really at a loss as to how this happened. I have an app that uses ARC. Most of the my view controllers register for NSNotifications. All registrations are done on the main thread.

当发生内存警告时,用于每个不可见选项卡的导航控制器为零,因此将被取消分配。在这种情况下,一个导航控制器及其视图控制器被释放,视图控制器在其dealloc方法期间崩溃了应用程序。

When a memory warning occurs, the navigation controller used for each non-visible tab is nil'd and is consequently deallocated. In this case, one navigation controller and its view controller were deallocated, and the view controller crashed the app during its dealloc method.

具体来说,它是从所有NSNotificationCenter中删除自己的通知。

Specifically, it was removing itself from all NSNotificationCenter notifications.

dealloc方法也在主线程中运行,所以我不知道这可能是一个线程问题。

The dealloc method also ran in the main thread, so I don't see how this could be a threading issue.

崩溃的行是 - [SearchTabViewController dealloc](SearchTabViewController.m:44)

代码中的那一行是: [[NSNotificationCenter defaultCenter] removeObserver:self];

出现实际的崩溃原因要 objc_msgSend 引用一个解除分配的对象。

The actual crash reason appears to be objc_msgSend referencing a deallocated object.

问题在于,此处只发送了2条消息, defaultCenter 消息发送到 NSNotificationCenter 类(它永远不会是一个无效的引用,因为它是一个类)和 removeObserver:消息到默认的中心对象(也永远不会被解除分配,因为它是一个单身人士)。

The problem with that is that there are only 2 messages being sent here, the defaultCenter message to the NSNotificationCenter class (which can never be an invalid reference because it's a class) and the removeObserver: message to the default center object (also can never be deallocated because it's a singleton).

引用的唯一其他对象是self,由于我们仍然处于该对象的dealloc方法,因此无法解除分配...基本上这次崩溃不应该发生。

The only other object referenced is self, which can't be deallocated yet because we're still in the "dealloc" method for that object... Basically this crash shouldn't have happened.

这里有什么我想念的吗?以下崩溃日志的相关部分:

Is there something I'm missing here? Relevant part of the crash log below:

Exception Type:  SIGSEGV
Exception Codes: SEGV_ACCERR at 0xe0000008
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                     0x000035b0 objc_msgSend + 16
1   Anghami Beta                        0x000c7473 -[SearchTabViewController dealloc] (SearchTabViewController.m:44)
2   CoreFoundation                      0x00003311 CFRelease + 101
3   CoreFoundation                      0x0000d95d -[__NSArrayM dealloc] + 141
4   Anghami Beta                        0x0033e73f -[EX2NavigationController .cxx_destruct] (EX2NavigationController.m:51)
5   libobjc.A.dylib                     0x00007f3d object_cxxDestructFromClass(objc_object*, objc_class*) + 57
6   libobjc.A.dylib                     0x000050d3 objc_destructInstance + 35
7   libobjc.A.dylib                     0x000053a7 object_dispose + 15
8   UIKit                               0x000cec89 -[UIViewController dealloc] + 1181
9   CoreFoundation                      0x00003311 CFRelease + 101
10  CoreFoundation                      0x0000da13 -[__NSArrayI dealloc] + 79
11  libobjc.A.dylib                     0x00005489 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 169
12  CoreFoundation                      0x00005441 _CFAutoreleasePoolPop + 17
13  CoreFoundation                      0x00095f41 __CFRunLoopRun + 1297
14  CoreFoundation                      0x00008ebd CFRunLoopRunSpecific + 357
15  CoreFoundation                      0x00008d49 CFRunLoopRunInMode + 105
16  GraphicsServices                    0x000052eb GSEventRunModal + 75
17  UIKit                               0x00057301 UIApplicationMain + 1121
18  Anghami Beta                        0x0000334d main (main.m:17)


推荐答案

因此事实证明崩溃日志具有误导性。在连接到启用了僵尸对象的调试器时,我最终能够实现它。崩溃的实际来源是一个装载器对象,它将该控制器作为委托,在控制器被释放后尝试调用其中一个委托方法。

So it turned out the crash log was misleading. I was able to eventually get it to happen while connected to the debugger with zombie objects enabled. The actual source of the crash was a loader object that had this controller as it's delegate, tried to call one of the delegate methods after the controller was deallocated.

现在在dealloc中,我没有加载器的委托,如果激活则取消加载,并且不再发生崩溃。

Now in dealloc, I nil the loader's delegate and cancel the loading if active, and voila no more crashes.

此外,值得注意的是这次崩溃拒绝在模拟器中发生,但几乎每次都发生在设备上。因此,当追踪奇怪的内存错误时,不幸的是僵尸工具并不总是一个可行的工具,因为它需要在模拟器中运行应用程序。

Also, it's worth noting that this crash refused to happen in the simulator, but happened almost every time on the device. So when tracking down weird memory errors, unfortunately the Zombies instrument is not always a viable tool because it requires the app to be run in the simulator.

所以下一个最好的事情是去编辑方案并在那里启用僵尸对象,然后在设备上构建和运行并等待它崩溃。您没有以这种方式获得完整的保留/发布历史记录,但在这种情况下,它可以提供足够的信息来追踪难以解决的问题。

So the next best thing is to go to Edit Scheme and enable zombie objects there, then build and run on device and wait for it to crash. You don't get the full retain/release history that way, but as in this case, it can give enough information to track down an otherwise elusive problem.

这篇关于SEGV_ACCERR在dealloc中调用[[NSNotificationCenter defaultCenter] removeObserver:self]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆