新しいウィンドウを作成する「Create window」というメニュー ボタンがあるとします。
MyWindowClass * window = [MyWindowClass new];
それを保持するために、可変配列に追加します (_articleArray = [NSMutableArray new]; として宣言および合成されます)。
[_articleArray addObject:window]
これはうまくいきます。私が含める場合:
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