2012-10-17 39 views
1

說我有一個名爲「創建窗口」創建一個新的窗口中的菜單按鈕:EXC_BAD_ACCESS從陣列中刪除窗口

MyWindowClass * window = [MyWindowClass new]; 

爲了留住它,我把它添加到一個可變數組(聲明,合成爲_articleArray = [NSMutableArray new];)

[_articleArray addObject:window] 

This works great。如果我包括:

NSLog(@"Windows in mem: %lu",_articleArray.count); 

每當我單擊按鈕並且屏幕上出現另一個窗口時,數字會遞增。現在

,如果我選擇附加到這個「創建窗口」功能,以確定當窗口關閉:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowClosed:) name:NSWindowWillCloseNotification object:window]; 

這將創建一個錯誤:

-(void) windowClosed:(NSNotification*)notification { 
    [_articleArray removeObject:[notification object]]; 
    NSLog(@"Windows in mem: %lu",_articleArray.count); 

的NSLog的遞減當我關閉如預期的那樣,但是隻要函數結束,它就會拋出一個EXC_BAD_ACCESS錯誤(代碼13,地址= 0,0)

0x7fff97878710: movq 24(%rax), %rax 

我很困惑。數字遞減,所以我只能認爲該功能正在工作。那麼這裏發生了什麼?

編輯:(LLDB)螺紋回溯

* thread #1: tid = 0x1c07, 0x00007fff97878710 libobjc.A.dylib`objc_msgSend_vtable13 + 16, stop reason = EXC_BAD_ACCESS (code=13, address=0x0) 
frame #0: 0x00007fff97878710 libobjc.A.dylib`objc_msgSend_vtable13 + 16 
frame #1: 0x00007fff97571503 Foundation`__NSFireTimer + 80 
frame #2: 0x00007fff993a6da4 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 
frame #3: 0x00007fff993a68bd CoreFoundation`__CFRunLoopDoTimer + 557 
frame #4: 0x00007fff9938c099 CoreFoundation`__CFRunLoopRun + 1513 
frame #5: 0x00007fff9938b6b2 CoreFoundation`CFRunLoopRunSpecific + 290 
frame #6: 0x00007fff8df260a4 HIToolbox`RunCurrentEventLoopInMode + 209 
frame #7: 0x00007fff8df25e42 HIToolbox`ReceiveNextEventCommon + 356 
frame #8: 0x00007fff8df25cd3 HIToolbox`BlockUntilNextEventMatchingListInMode + 62 
frame #9: 0x00007fff92ce3613 AppKit`_DPSNextEvent + 685 
frame #10: 0x00007fff92ce2ed2 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128 
frame #11: 0x00007fff92cda283 AppKit`-[NSApplication run] + 517 
frame #12: 0x00007fff92c7ecb6 AppKit`NSApplicationMain + 869 
frame #13: 0x0000000100006942 myApp`main + 34 at main.m:13 
frame #14: 0x00007fff9094f7e1 libdyld.dylib`start + 1 
+1

一旦將窗口對象添加到數組中,您可以釋放它,因爲數組將保留它。如果你不使用ARC,你會得到一個內存泄漏。您還需要從通知方法中的窗口中刪除觀察者。 – trojanfoe

+0

請發佈堆棧跟蹤。 – trojanfoe

+0

@trojanfoe在輸出窗口中沒有堆棧跟蹤,只是(lldb),然後我在上面突出顯示的EXC_BAD_ACCESS行顯示在主編輯器窗口中。我正在使用ARC,所以沒有解決方案A,但刪除觀察者似乎可能是這個問題 - 我現在無法弄清楚目前的情況如何,還會繼續嘗試,但是你能否幫我解決一些問題, d去了解它? –

回答

1

這個答案已經從評論搬到了這個問題的任擇議定書的要求

你需要確保你刪除了NSWindowWillCloseNotification觀察員在窗戶被破壞之前:

-(void) windowClosed:(NSNotification*)notification { 
    NSWindow *window = [notification object]; 
    [[NotificationCenter defaultCenter] removeObserver:self 
                name:NSWindowWillCloseNotification 
               object:window]; 
    [_articleArray removeObject:window]; 
    NSLog(@"Windows in mem: %lu",_articleArray.count); 
    ... 

並且還確保窗口有我ts​​屬性設置爲YES,以便在關閉後自行清理。