为什么不从NSNotificationCenter删除观察者:addObserverForName:usingBlock被调用

我很困惑,为什么在下面的代码中永远不会删除观察者。 在我看来,我有以下几点:

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

观察者永远不会被移除,并且每次发送通知时都会输出语句。 任何人可以提供任何指导?

当通过addObserverForName:将块推入堆栈时,该方法尚未返回,因此gpsObserver为零(在ARC下)或垃圾/未定义(不在ARC下)。 声明variables使用__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的回答)。 代码未经testing。

我发现实际上有一个内存泄漏,除非观察者被标记为__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]; }];