最近发现了两个坑
1.NSAssert在block里使用会造成retain cycle循环引用
2.使用[[NSNotificationCenter defaultCenter ]addObserverForName:]会造成这个通知多次执行,即使它所在的ViewController已经Dealloc了
- (id <NSObject>)addObserverForName:(nullable NSNotificationName)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block;
官方API给的注释是
The return value is retained by the system, and should be held onto by the caller in order to remove the observer with removeObserver: later, to stop observation.
这段话的大意是这个方法的返回值被系统持有,而且为了后续移除监听应该也被调用者持有。那么这里调用者是什么?可能指的是self,即当前控制器,也可能是指的当前的通知中心。
然后我尝试在dealloc方法里调用移除方法,在调用dismiss的时候移除这个监听,发现不管当前控制器是否释放掉,这个方法都会调用多次。进而证实这个方法的确是被系统持有的。唯一的区别就是如果当前控制器释放掉了,在它执行多次时添加断点,然后打印self,会发现打印的self的值并不存在,就是说前几次的执行不会造成任何实质性的影响,只有最后一次self有值时才会执行block里的方法。
所以建议谨慎使用[[NSNotificationCenter defaultCenter] addOserverForName: object: queue:usingBlock]方法,推荐使用传统常用的[[NSNotificationCenter defaultCenter] addObserver:selector:name:object]方法。嗯,我发现我用的比较牛逼有名的框架(eg. AFNetWorking, SDWebImage)都没有用addObserverForName,都使用的addObserver:Selector。所以还是跟着大神走哦!