iOS Block中的weakSelf/strongSelf
2015-12-18 10:25
393 查看
Objective C 的
示例代码:
clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:
在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,于是,strongSelf 就派上用场了:
如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。
Is the weakSelf/strongSelf dance really necessary when referencing self inside a non-retained completion called from a UIViewController?
Block是一个很实用的语法,特别是与GCD结合使用,可以很方便地实现并发、异步任务。但是,如果使用不当,Block 也会引起一些循环引用问题(
retain cycle)—— Block 会 retain ‘self’,而 ‘self‘ 又 retain 了 Block。因为在 ObjC 中,直接调用一个实例变量,会被编译器处理成 ‘self->theVar’,’self’ 是一个 strong 类型的变量,引用计数会加 1,于是,self retains queue, queue retains block,block retains self。
解决 retain circle
Apple 官方的建议是,传进 Block 之前,把 ‘self’ 转换成 weak automatic 的变量,这样在 Block 中就不会出现对 self 的强引用。如果在 Block 执行完成之前,self 被释放了,weakSelf 也会变为 nil。示例代码:
1 2 3 4 | __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakSelf doSomething]; }); |
1 2 3 45 | __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakSelf doSomething]; [weakSelf doOtherThing]; }); |
1 2 3 45 | __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ __strong __typeof(self) strongSelf = weakSelf; [strongSelf doSomething]; [strongSelf doOtherThing]; }); |
__strong确保在 Block 内,strongSelf 不会被释放。
总结
在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。
参考
I finally figured out weakSelf and strongSelfIs the weakSelf/strongSelf dance really necessary when referencing self inside a non-retained completion called from a UIViewController?
原文作者: lslin
原文链接: http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block/
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
原文链接: http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block/
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
相关文章推荐
- <转载>让iOS的应用程序在点击设备的home键返回桌面后,再次打开应用进入启动画面
- iOS TPKeyboardAvoiding自动识别键盘的高度
- IOS视频分解图片、图片合成视频
- ios启动程序时隐藏状态栏,启动后显示状态栏的方法
- iOS学习路线图
- problem parm crash 照相机的问题
- iOS开发——远程消息推送的实现
- Xcode 6之后创建PCH文件
- [IOS 开发] 获取当前设备可用内存及所占内存
- IOS string转NSURL为nil问题
- 17个提升iOS开发效率的必用工具
- iOS---tableView的一些内容
- iOS runtime 学习分享
- iOS开发之Socket
- iOS开发-进阶:FMDB使用(翻译)
- 实现ios手机QQ空间导航栏控制器时隐时现效果,kvo的应用
- masonry闲谈
- 在企业内部分发 iOS 应用程序
- C 语言关键字,标示符和注释
- ios8 设置导航栏颜色