当使用ARC的NSNotificationCenter代码块方法时,不会调用视图控制器dealloc

当我在视图控制器的-viewDidLoad:方法中使用-addObserverForName: object: queue: usingBlock: for NSNotificationCenter时, -dealloc方法最终不会被调用。

(当我删除-addObserverForName: object: queue: usingBlock: ,再次调用-dealloc 。)

使用-addObserver: selector: name: object:似乎没有这个问题。 我究竟做错了什么? (我的项目正在使用ARC。)

下面是我的实现的一个例子,以防万一我在这里做错了什么:

 [[NSNotificationCenter defaultCenter] addObserverForName:@"Update result" object:nil queue:nil usingBlock:^(NSNotification *note) { updateResult = YES; }]; 

在此先感谢您的帮助。

我已经尝试添加以下(无济于事):

 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if ([self isMovingFromParentViewController]) { [[NSNotificationCenter defaultCenter] removeObserver:self]; } } 

updateResult是一个实例variables,它阻止对象被该块保留的情况下被释放。

换句话说,你有一个保留周期。 对象保留块,块保留该对象。

您将需要创build一个弱或unsafe_unretained参考该实例及其variables,以放弃这种关系。

在通知区块之前添加以下内容:

 __unsafe_unretained YouObjectClass *weakSelf = self; 

或者(如果你在iOS5及以上)

 __weak YouObjectClass *weakSelf = self; 

然后,在该块内,通过新的弱引用来引用对象:

 [[NSNotificationCenter defaultCenter] addObserverForName:@"Update result"                         object:nil                          queue:nil                       usingBlock:^(NSNotification *note) {                         weakSelf.updateResult = YES;                       }]; 

请注意,保留周期本身并不是一件坏事。 有时你真的希望他们发生。 但这些都是你确定在特定时间之后周期会被破坏的情况(例如animation块)。 一旦程序块执行完成并从堆栈中移除,循环就会中断。

这很可能是因为你有一个保留周期。

当你的块隐式地保留自己时,这是典型的情况,并且自我保留块。 您将有一个保留周期,因为每个保留另一个保留周期,因此其retainCount从未达到零。

您应该激活警告-Warc-retain-cycles ,以警告您这些问题。

所以在你的情况下,你正在使用variablesupdateResult ,我认为这是一个实例variables,这隐含地保留self 。 你应该使用一个临时的弱variables来表示self,并且在你的block中使用这个variables,这样它就不会被保留下来,并且会破坏保留周期。

 __block __weak typeof(self) weakSelf = self; // weak reference to self, unretained by the block [[NSNotificationCenter defaultCenter] addObserverForName:@"Update result" object:nil queue:nil usingBlock:^(NSNotification *note) { // Use weakSelf explicitly to avoid the implicit usage of self and thus the retain cycle weakSelf->updateResult = YES; }]; 

这不是保留周期。

NSNotificationCenter持有块,块持有self 。 因为[NSNotificationCenter defaultCenter]是一个生活在所有应用程序生命周期中的单身人士,所以它保持self间接。