addObserverForName和remove observer [英] addObserverForName and removing observer

查看:250
本文介绍了addObserverForName和remove observer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在启用ARC的Cocoa代码上,我试图观察下面的窗口关闭事件。

On Cocoa code with ARC enabled, I tried to observe Window closing events like below.

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 。
但实际上,这个代码并不是dealloc ScanWindowController关闭Window后。
如果我使用对控制器的弱引用写下如下,则调用ScanWindowController的dealloc。

I thought this will remove all the references to the controller (c) after closing Window. But actually, this code does not dealloc ScanWindowController after closing Window. If I wrote like below using weak reference to the controller, dealloc of ScanWindowController is called.

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]];
}]; 

为什么第一个代码不起作用?

Why does the first code not work?

推荐答案

我认为保留周期在观察者数组和块之间。 observer 数组保存实际的观察者对象。只要观察者对象是活的,它保存块。该块保存观察者数组。

I think the retain cycle is between the observer array and the block. The observer array holds the actual observer object. So long as the observer object is alive, it holds the block. The block holds the observer array.

这保持 ScanViewController 作为副作用。我看不到任何证据表明 ScanViewController 持有对观察者的强引用。

This keeps the ScanViewController as a side effect. I see no evidence that the ScanViewController holds a strong reference to the observer.

我相信解决方案是删除观察者从观察者数组在块的结尾。另一种解决方案是不使用数组来保存观察者,只是一个 __ block id 变量。然后,在块的末尾将该变量设置为 nil

I believe the solution is to remove the observer from the observer array at the end of the block. Another solution would be to not use an array to hold the observer, just a __block id variable. Then, set that variable to nil at the end of the block.

这篇关于addObserverForName和remove observer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆