当前位置: 首页 > news >正文

weakSelf 和 strongSelf的区别和用处

block会copy要在block中使用的实变量,而copy会是变量的retainCount + 1,如若在不注意很容易造成循环引用。而所谓的循环引用的本质就是,两个对象相互引用,从而造成对象不能正常的dealloc。所以解决的办法就是让引用的一方是weak的,这样就使得相互引用的闭环被打破,能够正常的dealloc了。

 

1)weakSelf的使用:

Apple 官方的建议是,传进 Block 之前,把 ‘self’ 转换成 weak automatic 的变量,这样在 Block 中就不会出现对 self 的强引用。 

上图的代码中,backgroundTaskId是当前这个类的一个属性,在backgroundTaskId初始化的这个方法中,有一个block回调,在这个block的实现中访问需要访问Self,为了避免造成循环引用,此处给当前的Self取了个别名,并用__weak来修饰,目的是告诉编译器,此处是弱引用,不要retain 当前的这个类,也就是所谓的self。

2)为什么会出现strongSelf?

Apple 官方文档有讲到,如果在 Block 执行完成之前,self 被释放了,weakSelf 也会变为 nil。

clang给出的实例代码:

 

    __weak __typeof__(self) weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [weakSelf doSomething];

    });

 clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:

    __weak __typeof__(self) weakSelf = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [weakSelf doSomething];

        [weakSelf doOtherThing];

    });

 

 在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,

 于是,strongSelf 就派上用场了:

    __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 确保strongSelf在block中不会被释放。

 

所以就能理解SDWebImage中的那段代码,block在实现的过程中会对wself进行一次强引用,是为了防止在block还未执行完毕,wself在其他线程中被释放,使得wself为nil。

 

 简单的做个小结:

 1、在使用block时,如果block内部需要访问self的方法、属性、或者实例变量应当使用weakSelf

 2、如果在block内需要多次访问self,则需要使用strongSelf

 3、如果在block内部存在多线程环境访问self,则需要使用strongSelf

 4、block本身不存在多线程之分,block执行是否是多线程,取决于当前的持有者是否是以多线程的方式来调用它。

 

转载于:https://www.cnblogs.com/FZP5/p/8193716.html

相关文章:

  • 舆情分析系统技术解决方案及作用
  • 校园舆情信息热点话题监测解决方案
  • 转:ASP.NET MVC 将IListT导出Excel文档的泛型类
  • 信息惠民政策网络舆情怎么监测的系统技术解决方案
  • 微信扫码登录-JAVA
  • 今日新网络舆情信息监测收集技术解决办法
  • Spring深入研究:方法注入
  • 政企舆情监测软件好不好评判方法及使用功能介绍
  • oracle查看被锁的表和解锁
  • 网络舆情信息传播动态监测查询方法
  • python基础---递归函数 知识点自查填空题
  • 百度平台上的网络舆情信息怎么搜查的方法
  • 互联网舆情数据信息挖掘分析的方法
  • [luoguP3159] [CQOI2012]交换棋子(最小费用最大流)
  • 网络舆情事件发展趋势变化监测分析的方法
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • Android 控件背景颜色处理
  • JAVA SE 6 GC调优笔记
  • java小心机(3)| 浅析finalize()
  • Phpstorm怎样批量删除空行?
  • Vue2.x学习三:事件处理生命周期钩子
  • 阿里云前端周刊 - 第 26 期
  • 测试开发系类之接口自动化测试
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 蓝海存储开关机注意事项总结
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 你不可错过的前端面试题(一)
  • 前端面试之闭包
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 微服务框架lagom
  • MPAndroidChart 教程:Y轴 YAxis
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #define用法
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #QT(串口助手-界面)
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $.ajax()
  • (C++17) optional的使用
  • (C语言)二分查找 超详细
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (WSI分类)WSI分类文献小综述 2024
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (理论篇)httpmoudle和httphandler一览
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (十三)Maven插件解析运行机制
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)大道至简,职场上做人做事做管理
  • (转)负载均衡,回话保持,cookie