我通常使用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子类使用通知?
答案 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发送到一个解除分配的实例。