1
在啓用ARC的Cocoa代碼上,我嘗試觀察如下的窗口關閉事件。addObserverForName和刪除觀察者
ScanWindowController * c = [[ScanWindowController alloc] initWithWindowNibName:@"ScanWindowController"];
[scanWindowControllers addObject:c];
[c showWindow:nil];
NSMutableArray *observer = [[NSMutableArray alloc] init];
observer[0] = [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[scanWindowControllers removeObject:c];
[[NSNotificationCenter defaultCenter] removeObserver:observer[0]];
}];
我想關閉 窗口後,這將刪除控制器(C)的所有引用。 但實際上,此代碼在關閉Window之後不會解除對ScanWindowController的分配。 如果我使用弱引用來編寫控制器,則調用ScanWindowController的dealloc。
ScanWindowController * c = [[ScanWindowController alloc] initWithWindowNibName:@"ScanWindowController"];
[scanWindowControllers addObject:c];
[c showWindow:nil];
__weak ScanWindowController * weak_c = c;
NSMutableArray *observer = [[NSMutableArray alloc] init];
observer[0] = [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[scanWindowControllers removeObject:weak_c];
[[NSNotificationCenter defaultCenter] removeObserver:observer[0]];
}];
爲什麼第一個代碼不起作用?
** observer **是局部變量,ARC已啓用。所以,在函數結束時,** observer **數組和內容應該被釋放? –
ARC確實**不保證當局部變量超出範圍時,由局部變量引用的對象被銷燬。 *一個引用將被釋放,但這並不意味着該對象被釋放。該塊包含對它的另一個引用,只要觀察對象(由'-addObserverForName:object:queue:usingBlock:'返回的那個)存在,該塊就會保留。只要存在'observer'數組,這個觀察對象就存在,這就是保留週期。 –
啊,我明白了!所以,我寫了** arr = @ []; arr [0] = arr; **。只要在塊末尾調用** [observer removeAllObjects] **解決了參考循環。謝謝 ! –