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