我很困惑为什么在以下代码中永远不会删除观察者。在我的viewDidAppear中,我有以下内容:
-(void)viewDidAppear:(BOOL)animated{
id gpsObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:FI_NOTES[kNotificationsGPSUpdated]
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
NSLog(@"run once, and only once!");
[[NSNotificationCenter defaultCenter] removeObserver:gpsObserver];
}];
}
观察者永远不会被删除,并且每次发送通知时都会输出语句。任何人都可以提供任何指导吗?
答案 0 :(得分:30)
当块被addObserverForName:
推入堆栈时,该方法尚未返回,因此gpsObserver为nil(在ARC下)或garbage / undefined(不在ARC下)。使用__block
外部声明变量,这应该可以。
__block __weak id gpsObserver;
gpsObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:FI_NOTES[kNotificationsGPSUpdated]
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
NSLog(@"run once, and only once!");
[[NSNotificationCenter defaultCenter] removeObserver:gpsObserver];
}];
我添加了__weak以确保没有内存泄漏(根据Matt的回答)。代码未经测试。
答案 1 :(得分:11)
我发现实际上存在内存泄漏,除非观察者同时标记为__block
和__weak
。使用工具确保self
没有被重复;我敢打赌。但是,这可以正常工作(来自我的实际代码):
__block __weak id observer = [[NSNotificationCenter defaultCenter]
addObserverForName:@"MyMandelbrotOperationFinished"
object:op queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
// ... do stuff ...
[[NSNotificationCenter defaultCenter]
removeObserver:observer
name:@"MyMandelbrotOperationFinished"
object:op];
}];