转自  http://www.cnblogs.com/zhang-chi/p/5532272.html
ARC下,关于block里面使用self、weakSelf、strongSelf,理解一直没有特别的透彻,今天花时间研究了一下,总结如下:
其实一共就涉及到两个问题:
1.是否循环引用了
2.block里面的代码,不一定执行到哪行时,VC可能就释放了,self就为nil了,那么你到底想让代码在这种情况下如何执行。
其实到底用self、weakSelf还是strongSelf,就是上面两个问题的排列组合
有种典型的写法:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__weak __typeof__(self) weakSelf = self;
dispatch_async(queue, ^{__typeof__(self) strongSelf = weakSelf;[strongSelf assitFunc1];
});

首先我的结论是,所有情况下,这么写是不会出什么问题的(当然也好多情况下不用这么写),唯一可能出问题的地方就是要保证block里面的代码能够被执行到,否则就和循环引用一样,是不会释放VC的。什么情况会执行不到?比如queue里面已经有1万个任务,然后正在串行执行,当然这里说的是理论上,所以一般也不会有这种情况。
不会出问题的原因是:不会造成循环引用,因为没有对self持有(其实是block代码期间持有了,执行完毕就不持有了);block里的代码一定会执行,因为strongSelf会保证在block代码执行完毕之前self不会被释放(延迟了VC的生命周期),并且执行的时候strongSelf一定不会为nil。所以没有问题。
然后说下weak和strong的作用:
1.weakSelf,不增加self的引用计数,然后你还可以使用它,所以它能防止循环引用(该释放释放,和weakSelf怎么用完全没关系)。
2.strongSelf,在定义的区域内保证指向的内容不被释放,所以他用在确保代码执行的时候。(防止self变成nil,延迟self的生命)。
到底怎么用有以下情况:
1.不管使用self,还是strongSelf,都延迟了VC释放的时间,至少要执行完block。
2.如果block是临时的block,例如在ViewDidLoad里面写上面的代码。直接使用self就可以达到同样的效果,不会出现内存泄露,因为虽然block持有self,但是self并没有持有block,没有成环。并且注意,self一定会晚于或者等于block执行完毕的时间释放。就算执行到block中的某行代码,并不在当前VC了,也不会crash,因为self没有释放。
所以好多时候,如果block和self没有成环,我们就直接使用self就行了。无需定义weakSelf和strongSelf。但是有时候没有成环,我们依然使用了weakSelf,这时其实可以达到这样的效果:如果VC释放了(不在当前页了),那么由weakSelf方法调用的函数,其实都不执行了,就达到了节省资源的目的,需要注意的是对于nil的处理,避免crash。既用weak又用strong就没必要了,就和直接使用self时一个效果。
3.如果成环了,那么一定会使用weak。至于block里面的代码是全部使用weak还是全部使用strong,就取决于当self变成nil时,你想让代码如何执行,如果无论如何你都想执行block里面的代码,那么就用strong,如果想要self为nil时,不执行一些代码,则凡是使用weakSelf的函数都不会被执行,也必须注意可能会crash的地方。
结论:
1.不成环,并且想让block代码什么情况下都执行:两种方式:A全部使用self就行;B外面定义weak,block里面用strong,也行,多次一举。
2.不成环,并且想让block代码在当前VC释放的情况下不执行:两种方式:A外面定义weak,里面使用weak,然后注意nil可能会crash的地方(加判断);B外面定义weak,block里面使用strong(或者直接使用self),自己加if判断,否是在当前页面,不在当前页面不执行。
3.成环,想让block代码无论如何都执行:必用weak。block里面用strong。
4.成环,想让block代码在当前VC释放的情况下不执行:两种方式:A必用weak,block里面用strong,则自己加if判断不在当前页面就不执行;B,block里面使用weak,注意nil可能导致crash的地方。
重点注意:弄清楚block到底被谁持有,例如UIView的animateWithDuration方法,大部分时候写的dispatch,传参等,都没有成环,是不用定义weak和strong的。

转载于:https://www.cnblogs.com/SnowStark/p/5685907.html

block里的self、weakSelf、strongSelf相关推荐

  1. iOS中block的详解weakSelf、strongSelf-转自唐巧

    1 我们知道,在使用 block 的时候,为了避免产生循环引用,通常需要使用 weakSelf 与 strongSelf,写下面这样的代码: __weak typeof(self) weakSelf ...

  2. 如何避免在Block里用self造成循环引用

    原文:http://blog.csdn.net/zhangao0086/article/details/38273239 一般来说我们总会在设置Block之后,在合适的时间回调Block,而不希望回调 ...

  3. 快速定位Product assignment block里对应的修改逻辑使用的function module

    Created by Jerry Wang, last modified on May 16, 2014 假设需要debug Product overview page里当修改Notes assign ...

  4. Attachment assignment block里选择的文件是如何传到Netweaver服务器的

    使用Chrome debug attachment upload page:从local laptop上选择一个file之后,断点触发: 前端取得user选中的file name: 点Attach b ...

  5. Organizational Data assignment block里value help的determine逻辑

    Created by Jerry Wang, last modified on Apr 27, 2015 WebUI里发现Sales Org unit的value help里显示的entry只是系统全 ...

  6. Attachment assignment block里选择的文件是如何传到application server

    Created by Jerry Wang, last modified on Dec 12, 2014 使用Chrome debug attachment upload page:从local la ...

  7. (0033) iOS 开发之Block 的基础用法及注意事项2

    循环引用之String 当在block内部使用成员变量的时候,比如 @interface ViewController : UIViewController { NSString *_string; ...

  8. Block的循环引用

    2019独角兽企业重金招聘Python工程师标准>>> 在ios常见的循环引用中曾经提到过block: 看看上面最基本的block循环应用,self包含block,block包含了s ...

  9. Block详解------已完结

    1.Block的使用 Block是什么? 块,封装了函数调用以及调用环境的OC对象, Block的声明 //1. @property (nonatomic, copy) void(^myBlock1) ...

最新文章

  1. 仅靠合成数据就能实现真实人脸分析!微软这项新研究告别人工标注
  2. scipy 图像处理-深度学习
  3. Linux_Bash脚本基础
  4. python读取文件读不出来-python文件读取失败怎么处理
  5. 软件开发本质论——自然之路
  6. PHP-FPM进程数的设定
  7. 桌面圣诞树酷炫特效合集【含动态效果展示及网盘源码分享】
  8. python sorted函数倒序_Python sorted函数
  9. magisk安装失败_刷入magisk+TWRP+Riru+edxposed教程!
  10. 怎样更改计算机的sid,关于Windows系统sid修改方法
  11. 为DB2 新增加的用户不能直接使用db2命令的解决办法
  12. 利用Redis原子计数器incr实现计数器及接口限流
  13. ps 仿章工具的使用
  14. 事件推送网关:让cmdb告别“花瓶”
  15. 二见钟情之UML时序图
  16. iOS In-App Purchase 内购之创建内购产品
  17. Chrome现在会在地址中隐藏WWW和HTTPS://。 你关心?
  18. 图解 CMMI 2.0之(七)能力域
  19. 渠道广告联盟SDK接入思路总结
  20. 项目管理 | 什么是项目管理计划?

热门文章

  1. 蓝桥杯第八届省赛JAVA真题----承压计算
  2. request获取url的参数编码问题
  3. java难学还是pythonnanxue_关于python:为什么numpy中的“ NaN”比“ -np.inf”更小?
  4. mysql innodb隔离级别_浅析MySQL InnoDB的隔离级别
  5. linux wifi pro6818,GEC6818连接Ubuntu,下载程序至开发板
  6. cfree运行程序错误_C/C++程序调试和内存检测
  7. c++创建二叉树_数据结构:查找(4)|| 平衡二叉树
  8. springcloud服务发现
  9. 机器学习笔记(五)续——朴素贝叶斯算法的后验概率最大化含义
  10. 《个人信息保护法》,教我如何做产品!