这是删除通知观察者的更好方法

时间:2012-04-06 06:14:26

标签: iphone ios ipad nsnotification

我通常使用NSNotification,如下例所示:

在viewDidLoad中:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bar:) name:kName2 object:nil];

在viewDidUnload和dealloc中:

[[NSNotificationCenter defaultCenter] removeObserver:self];

但是一位朋友告诉我,我不应该使用[[NSNotificationCenter defaultCenter] removeObserver:self];,因为它将删除所有观察者,包括超类。他建议我使用以下代码逐个删除观察者。

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kName2 object:nil];

我检查了ASIHttpRequest库的代码(https://github.com/pokeb/asi-http-request)。它遵循我朋友的建议。

我想知道我的朋友是否正确?在我看来,由于当前实例将是卸载或dealloc,超类的通知也是无用的。并且是否有任何系统UIViewController子类使用通知?

4 个答案:

答案 0 :(得分:12)

你的朋友是100%正确的。但是,如果删除dealloc中的所有通知观察,则无关紧要 您提到了viewDidUnload,并且情况完全不同,因为卸载的对象将保持活动状态,并且您不知道何时再次添加超类的通知观察。如果将它们添加到viewDidLoad中,则不会出现问题。如果将它们添加到init方法中,您只会丢失一堆重要的通知观察结果。

删除具有特定名称的观察结果是很好的做法,应该从头开始。

答案 1 :(得分:8)

如果要删除所有使用的通知,

[[NSNotificationCenter defaultCenter] removeObserver:self];

如果您要删除您使用的特定通知,

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];

当您不再需要任何通知时,第一种方法很简单。

答案 2 :(得分:1)

当对象消失时,在[[NSNotificationCenter defaultCenter] removeObserver:self];方法中使用dealloc是安全的。

ViewDidUnload方法中,您最好逐个删除每个观察者,因为对控制器的引用仍然存在(并且相应的viewDidLoad应该将它们全部添加回来)。

答案 3 :(得分:0)

我用第一种方式,我从未想过它是否正确。如果正在调用dealloc,那么对象(超级)也将被解除分配。你绝对不想要的是将NSNotification发送到一个解除分配的实例。