Block的循环引用
2019獨角獸企業(yè)重金招聘Python工程師標準>>>
在ios常見的循環(huán)引用中曾經(jīng)提到過block:
看看上面最基本的block循環(huán)應用,self包含block,block包含了self中的變量val,所以形成了循環(huán)應用,編譯器給出了循環(huán)引用的警告,當然不是所有的block循環(huán)引用編譯器都能給出警告,所以不要只依賴編譯器的警告來判斷循環(huán)引用,如:
解決的辦法當然是使用__weak來修飾self
__weak typeof(self) weakSelf = self; blkk = ^{[weakSelf showLog]; }; blkk();-------------------------------凌亂分割線-------------------------------
正常在棧上的block引用self是不會引起循環(huán)應用的,所以可以不使用weak來修飾self
void (^blkk)(void) = ^{[self showLog]; }; blkk();但是因為block的使用附有__strong的原因,雖然不會有循環(huán)引用,但是也會起到延長self對象的生命周期的效果,直到棧上的block釋放了,才會釋放self。
因此釋放self可能會讓程序出現(xiàn)問題,假如self監(jiān)聽了某些通知而修改公共資源什么的,所以這種情況下最好也使用weakself。
當然你也可能不希望self提前釋放,因為你的block回調(diào)后需要進行完整操作,假如self釋放了,你無法在block回調(diào)后來處理一些其他的事情,這時候你可以選擇不使用weakself,也可以使用weakself+strongself。先看看weakself+strongself的寫法:
__weak __typeof__(self) weakSelf = self;createdTask = [self.sessionManagerdataTaskWithRequest:requestcompletionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {dispatch_async(self.responseQueue, ^{__strong __typeof__(weakSelf) strongSelf = weakSelf; .....上面是AFNetworking的源碼,在block前用了weakself,在block里用了strongself,這樣做和直接不使用weakself有什么區(qū)別呢。
| ? | block回調(diào)前結束self | block回調(diào)后結束self |
| 不使用weakself | self 不釋放 | self不釋放 |
| weakself+strongself | self已釋放 | self不釋放 |
| 使用weakself | self已釋放 | self已釋放 |
所以根據(jù)情況的不同,大家可以選擇使用哪種方式。當然最無腦的推薦還是使用weakself
轉(zhuǎn)載于:https://my.oschina.net/iq19900204/blog/739755
總結
以上是生活随笔為你收集整理的Block的循环引用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: clientHeight.offsetH
- 下一篇: Linked List Cycle