objective-c - 将对象添加到 NSArrayController 时与内存相关的崩溃

标签 objective-c cocoa memory-management

我正在编写一个简单的 ObjC2.0/Cocoa 应用程序,但我遇到了崩溃。不熟悉 Cocoa 或 ObjC,我不知道为什么。

导致问题的代码是 TableListCon.m

当我将文件夹拖到 NSTableView 上时,它会调用 addDirectoryToList - 它递归地循环遍历此目录中包含的所有文件,对每个文件调用 addFileToList

当我将单个文件拖到表格 View 上时,它会直接调用addFileToList。这可以正常工作,但在调试器控制台中它显示以下消息:

tvnamergui(2612) malloc: *** error for object 0x144ab0: double free
*** set a breakpoint in malloc_error_break to debug

或者,如果我拖放一个文件夹,则不会出现此类消息,它会直接拖放到 GDB,并带有以下回溯:

(gdb) bt
#0  0x95cee688 in objc_msgSend ()
#1  0x921e2e4f in NSPopAutoreleasePool ()
#2  0x917b4b10 in NSCoreDragReceiveProc ()
#3  0x95f9e1b0 in DoDropMessage ()
#4  0x95f9dc11 in CoreDragMessageHandler ()
#5  0x960f0d21 in __CFMessagePortPerform ()
#6  0x961128e8 in CFRunLoopRunSpecific ()
#7  0x96112cd8 in CFRunLoopRunInMode ()
#8  0x924892c0 in RunCurrentEventLoopInMode ()
#9  0x92489012 in ReceiveNextEventCommon ()
#10 0x92488f4d in BlockUntilNextEventMatchingListInMode ()
#11 0x914e0d7d in _DPSNextEvent ()
#12 0x914e0630 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#13 0x914d966b in -[NSApplication run] ()
#14 0x914a68a4 in NSApplicationMain ()
#15 0x000022a0 in main (argc=1, argv=0xbffff74c) at /Users/dbr/Desktop/tvnamergui/main.m:13

更奇怪的是,如果我先拖动单个文件,我会收到double free 错误,但随后我可以将文件夹拖放到上面而不会发生崩溃(并且一切正常)

[ArrayCon addObject:cfile];运行时它总是死掉(评论这一行可以阻止崩溃,但显然会破坏功能!)

编辑:感谢smorgan's answer (使用NSZombieEnabled),我有一个更有用的错误消息:

*** -[CFArray release]: message sent to deallocated instance 0x155a70

最佳答案

虽然我无法针对您的情况给出具体答案,但调试此类过度发布崩溃的最佳方法是 turn on NSZombieEnabled这样您就可以轻松地看到哪些对象被过度释放。

编辑:查看您的项目后,我相信您的问题实际上出在 AppCon 初始值设定项中。您将成员变量“theFiles”设置为自动释放的数组,并且当您使用保留(好吧,复制)属性时,您没有使用属性语法(self.theFiles = ...)设置它,所以您是绕过自动生成的 setter 来正确处理内存管理。当稍后尝试更新该属性时,它将尝试释放错误地未保留的旧值。这很可能是您在僵尸日志记录中看到的数组。

简而言之,改变

theFiles = [NSMutableArray arrayWithObjects:...];

self.theFiles = [NSMutableArray arrayWithObjects:...];

并确保在分配给属性时始终使用 self.foo (或显式的 [self setFoo:] 形式)。

关于objective-c - 将对象添加到 NSArrayController 时与内存相关的崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/841901/

相关文章:

objective-c - 删除发送到 UILabel 的数据

iphone - 没有推送通知的系统范围警报

objective-c - 无法停止一次性通知?

cocoa-touch - 在layout/layoutSubviews方法中布局 subview 是否更好?

memory-management - C++/CLI 资源管理困惑

ios - 给定一个 NSDictionary 对象数组如何获取所有键?

macos - 如何使用快捷方式弹出菜单栏?

c - 为什么我不能使用 "fgets"将字符串读取到我的结构元素中?

c - C 中的二维结构数组 - 如何声明和使用

objective-c - NSViewController 中的第一响应者