最近發(fā)現(xiàn)了兩個(gè)坑
1.NSAssert在block里使用會(huì)造成retain cycle循環(huán)引用
2.使用[[NSNotificationCenter defaultCenter ]addObserverForName:]會(huì)造成這個(gè)通知多次執(zhí)行迁筛,即使它所在的ViewController已經(jīng)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.
這段話的大意是這個(gè)方法的返回值被系統(tǒng)持有妹笆,而且為了后續(xù)移除監(jiān)聽?wèi)?yīng)該也被調(diào)用者持有庆猫。那么這里調(diào)用者是什么抠璃?可能指的是self,即當(dāng)前控制器,也可能是指的當(dāng)前的通知中心。
然后我嘗試在dealloc方法里調(diào)用移除方法疙教,在調(diào)用dismiss的時(shí)候移除這個(gè)監(jiān)聽,發(fā)現(xiàn)不管當(dāng)前控制器是否釋放掉伞租,這個(gè)方法都會(huì)調(diào)用多次贞谓。進(jìn)而證實(shí)這個(gè)方法的確是被系統(tǒng)持有的。唯一的區(qū)別就是如果當(dāng)前控制器釋放掉了葵诈,在它執(zhí)行多次時(shí)添加斷點(diǎn)经宏,然后打印self,會(huì)發(fā)現(xiàn)打印的self的值并不存在驯击,就是說前幾次的執(zhí)行不會(huì)造成任何實(shí)質(zhì)性的影響,只有最后一次self有值時(shí)才會(huì)執(zhí)行block里的方法耐亏。
所以建議謹(jǐn)慎使用[[NSNotificationCenter defaultCenter] addOserverForName: object: queue:usingBlock]方法徊都,推薦使用傳統(tǒng)常用的[[NSNotificationCenter defaultCenter] addObserver:selector:name:object]方法。嗯广辰,我發(fā)現(xiàn)我用的比較牛逼有名的框架(eg. AFNetWorking, SDWebImage)都沒有用addObserverForName暇矫,都使用的addObserver:Selector主之。所以還是跟著大神走哦!