View controller dealloc not called when using NSNotificationCenter code block method with ARC

强颜欢笑 提交于 2019-12-04 04:58:30

updateResult is an instance variable which prevents the object from being deallocated as it is retained by that block.

In other words, you got a retain cycle. The object retains the block and the block retains the object.

You will need to create a weak or unsafe_unretained reference to that instance and its variable for loosing that relationship.

Add the following prior to your notification block:

__unsafe_unretained YouObjectClass *weakSelf = self;

or (in case you are on iOS5 and above)

__weak YouObjectClass *weakSelf = self;

Then, within that block, reference the object via that new weak reference:

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

Please note that retain-cycles are not a bad thing per se. Sometimes you actually want them to happen. But those are instances where you are certain that the cycle will be broken after a specific time (e.g. Animation Blocks). The cycle is broken once the block has executed and is removed from the stack.

This is very likely because you have a retain cycle.

This is typically the case when your block implicitly retain self, and self retains the block in a way. You will have a retain cycle as each one retains the other one, and their retainCount thus never reach zero.

You should activate the warning -Warc-retain-cycles that will warn you about such issues.

So in your case, you are using the variable updateResult, which I assume is an instance variable, and this implicitly retain self. You should instead use a temporary weak variable to represent self, and use this in your block, so that it does not get retained and you break the retain cycle.

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

This is not retain cycle.

NSNotificationCenter hold the block, block is hold self. Because [NSNotificationCenter defaultCenter]is a singleton living in all app life cycle, So it hold self indirect.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!