NSDrawer委托指向解除分配的对象?

时间:2010-05-31 18:46:35

标签: objective-c cocoa delegates

用户已使用下面列出的堆栈跟踪发送崩溃报告(我自己无法重现崩溃,但此用户报告的每次其他崩溃都是有效的错误,即使我无法重现效果)。该应用程序是一个引用计数的Objective-C / Cocoa应用程序。

如果我正确解释它,则会因尝试向已释放的对象发送drawerDidOpen:消息而导致崩溃。应该接收drawerDidOpen:的唯一对象是抽屉的委托对象(没有任何对象注册接收抽屉通知),抽屉的委托对象通过XIB / NIB文件实例化,连接到委托出口抽屉,并没有在其他地方引用。

鉴于此,我如何防止代理人在抽屉通知之前获得dealloc'd?或者,或者,我误解了可能导致崩溃的原因是什么?

崩溃日志/堆栈跟踪:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Application Specific Information:
objc_msgSend() selector name: drawerDidOpen:

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                 0x00007fff8272011c objc_msgSend + 40
1   com.apple.Foundation            0x00007fff87d0786e _nsnote_callback + 167
2   com.apple.CoreFoundation        0x00007fff831bcaea __CFXNotificationPost + 954
3   com.apple.CoreFoundation        0x00007fff831a9098 _CFXNotificationPostNotification + 200
4   com.apple.Foundation            0x00007fff87cfe7d8 -[NSNotificationCenter postNotificationName:object:userInfo:] + 101
5   com.apple.AppKit                0x00007fff8512e944 _NSDrawerObserverCallBack + 840
6   com.apple.CoreFoundation        0x00007fff831d40d7 __CFRunLoopDoObservers + 519
7   com.apple.CoreFoundation        0x00007fff831af8c4 CFRunLoopRunSpecific + 548
8   com.apple.HIToolbox             0x00007fff839b8ada RunCurrentEventLoopInMode + 333
9   com.apple.HIToolbox             0x00007fff839b883d ReceiveNextEventCommon + 148
10  com.apple.HIToolbox             0x00007fff839b8798 BlockUntilNextEventMatchingListInMode + 59
11  com.apple.AppKit                0x00007fff84de8a2a _DPSNextEvent + 708
12  com.apple.AppKit                0x00007fff84de8379 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 155
13  com.apple.AppKit                0x00007fff84dae05b -[NSApplication run] + 395
14  com.apple.AppKit                0x00007fff84da6d7c NSApplicationMain + 364
15  (my app's identifier)           0x0000000100001188 start + 52

编辑:澄清一下:这次崩溃发生在数千甚至数万个几乎相同的使用场景中。我没有在代码中的任何地方保留/ release / alloc / dealloc / anything-memory-management委托对象;我没有为我的代码中的任何抽屉通知注册任何对象;我的代码没有指向委托对象的变量(也没有ivars)。

对我而言,当NIB被卸载时(就像Cocoa系统在文档窗口关闭时所做的那样),抽屉的委托对象在抽屉对象本身之前被解除了,但是Cocoa系统应该防止这种情况发生(并且似乎在绝大多数情况下都能正确处理它)。

1 个答案:

答案 0 :(得分:1)

该代表已被释放到释放点,而没有首先从通知中心取消注册(在这种情况下,代表团是通过通知中心,而不是直接)。

一个简单的解决方法是从您委托的NSNotificationCenter's方法中调用-removeObserver: -dealloc方法。


检查回溯 - 通过通知中心发生崩溃。最有可能的是,当通过setDelegate:(通过NIB文件)连接类时,它是作为通知观察者完成的。

无论如何,通知中心和您的对象之间的关系与IB中的对象和您的对象之间的关系相同;弱。也就是说,没有retain因此,你的委托被过早释放(或者,你在某处过度释放了对象)。

在任何情况下,您都需要确保您的委托在其有效期内由某个地方保留。