addObserverForName和删除观察者(addObserverForName and re

2019-10-18 14:08发布

可可代码ARC启用,我试着观察窗正在关闭的事件,如下面。

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)的所有引用。 但实际上,这个代码不关闭窗口后的dealloc 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]];
}]; 

为什么第一个代码不行?

Answer 1:

我认为保留周期是之间observer阵列和块。 的observer阵列保存实际观测对象。 只要观察对象是活的,它拥有该块。 块保持observer阵列。

这使ScanViewController的副作用。 我看不出有任何证据表明ScanViewController拥有很强的参考观察者。

相信该溶液,以除去从观察者observer在块的末尾阵列。 另一解决方案是不使用阵列以保持观察者,只是一个__block id变量。 然后,设置该变量nil在块的末尾。



文章来源: addObserverForName and removing observer