代码之家  ›  专栏  ›  技术社区  ›  dbr

将对象添加到NSarrayController时出现与内存相关的崩溃

  •  0
  • dbr  · 技术社区  · 15 年前

    我正在编写一个简单的objc2.0/cocoa应用程序,我遇到了一个崩溃。不熟悉可可或奥比奇,我不知道为什么……

    导致问题的代码是 TableListCon.m

    当我将一个文件夹拖到InstableView上时,它调用 addDirectoryToList -它递归地循环此目录中包含的所有文件,调用 addFileToList 在每一个。

    当我将一个文件拖到TableView上时,它调用 添加文件者 直接。这正常工作,但在调试器控制台中显示以下消息:

    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
    
    1 回复  |  直到 15 年前
        1
  •  3
  •   smorgan    15 年前

    虽然我不能为您的案例给出具体的答案,但是调试过度发布崩溃的最佳方法是 turn on NSZombieEnabled 所以你可以很容易地看到什么物体被过度释放了。

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

    简而言之,改变

    theFiles = [NSMutableArray arrayWithObjects:...];
    

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

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