我正在写一个简单的ObjC2.0 / Cocoa应用程序,我正在崩溃..不熟悉Cocoa或ObjC,我无法理解为什么......
导致问题的代码是TableListCon.m
当我将文件夹拖到NSTableView上时,它会调用addDirectoryToList
- 它会递归循环遍历此目录中包含的所有文件,并在每个文件上调用addFileToList
。
当我将单个文件拖到tableview上时,它会直接调用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
答案 0 :(得分:3)
虽然我无法针对您的情况给出具体答案,但调试此类过度崩溃的最佳方法是turn on NSZombieEnabled,这样您就可以轻松查看哪些对象被过度释放。
编辑:查看项目后,我相信您的问题实际上在AppCon初始化程序中。您正在将成员变量“theFiles”设置为自动释放的数组,并且在使用保留(井,复制)属性时,您不是使用属性语法(self.theFiles = ...)设置它,因此您是绕过自动生成的setter,正确处理内存管理。当某些事情稍后尝试更新该属性时,它将尝试释放错误地未保留的旧值。这很可能是你在僵尸记录中看到的数组。
简而言之,改变
theFiles = [NSMutableArray arrayWithObjects:...];
到
self.theFiles = [NSMutableArray arrayWithObjects:...];
并确保在分配属性时始终使用self.foo(或显式[self setFoo:]表单)。