gpt4 book ai didi

objective-c - NSDrawer 委托(delegate)指向已释放的对象?

转载 作者:行者123 更新时间:2023-12-03 18:05:19 25 4
gpt4 key购买 nike

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

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

鉴于此,我如何防止委托(delegate)在抽屉通知之前被释放?或者,我误解了什么可能导致崩溃?

崩溃日志/堆栈跟踪:

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

编辑:澄清一下:这种崩溃发生在数千甚至数万个几乎相同的使用场景中。我不会在代码中的任何地方保留/释放/分配/释放/任何内存管理委托(delegate)对象;我没有在我的代码中为任何类型的抽屉通知注册任何对象;我的代码没有指向委托(delegate)对象的变量(也没有 ivars)。

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

最佳答案

委托(delegate)已被释放到释放点,而无需首先从通知中心取消注册(在这种情况下,委托(delegate)是通过通知中心而不是直接进行的)。

一个简单的修复方法是从委托(delegate)的 -dealloc 方法中调用 NSNotificationCenter 的 -removeObserver: 方法。

<小时/>

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

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

无论如何,您需要确保您的委托(delegate)在其有用期间被某处保留。

关于objective-c - NSDrawer 委托(delegate)指向已释放的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2945397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com