-
建议在 viewWillAppear中加入通知,在viewWillDisappear中移除通知(不建议这么做,会引起 bug) - block 不一定造成循环引用。如果调用 block 的对象与类本身的对象(也就是self)没有所属关系,即拥有 block 的对象不是 self 创建的。如:单例对象,则不会造成循环引用。如我们常用的
AFNetworking
,一般情况下,我们会创建一个单例对象进行网络请求,所以我们在用的时候,就不需要考虑其回调可能引发的循环引用的问题。
关于通知的用法:
添加监听
//oc
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(arrayValueChange) name:@"kUpDownTranslateChange" object:nil];
监听方法
-(void)arrayValueChange{
}
移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self];
不建议添加监听
放在viewWillAppear
中,移除通知
建议放在viewWillDisappear
为什么呢?
首先,通知必须在对应的位置移除对其监听,否则会重复添加通知,导致产生bug;
再者,不建议放在viewWillAppear,因为viewWillAppear中加入通知,就必须在viewWillDisappear中移除通知,否则可能会循环添加。如果我们使用
NotificationCenter.default.removeObserver(self)
移除通知的话,
可能会将其他不该移除的通知移除。
实际开发中,我遇到以下bug
在viewWillDisappear
调用NotificationCenter.default.removeObserver(self)
导致func tableViewSelectionDidChange(_ notification: Notification) {}
方法无法触发。
不能触发的原因很明显,是NotificationCenter.default.removeObserver(self)
导致的,说明func tableViewSelectionDidChange(_ notification: Notification) {}
方法是NotificationCenter
添加的监听
系统中使用NotificationCenter
添加监听的肯定不止这一个方法,故不建议在viewWillAppear
添加监听,viewWillDisappear
移除监听。
建议在
viewDidLoad
中添加监听,deinit
或dealloc
中移除监听。
2021年 3 月 11 日补充
使用 KVO 时,发现新bug:
Thread 1: "Cannot remove an observer < 0x600003ef1880> for the key path \"backupSpeed\" from <UpDownManager 0x600003c984e0> because it is not registered as an observer."
推荐链接:https://blog.csdn.net/chokshen/article/details/86304028
此 bug 是因为监听没有被添加就被移除导致了的。
在开发的过程中可能遇到页面初始化了,但没有加载的情况。此时,页面注销的时候会调用dealloc
、deinit
方法,但却始终没有调用viewDidLoad
方法。
如推荐文章所说,可以加一个判断isViewLoaded
当然也可以把添加监听
放在viewWillAppear
中,移除监听放在viewWillDisappear
中。
网友评论