iOS开发之 __block 与 __weak的区别理解

2023-11-07

资料来源1
资料来源2

__block对象在block中是可以被修改、重新赋值的。

使用了__weak修饰符的对象,作用等同于定义为weak的property。自然不会导致循环引用问题,因为苹果文档已经说的很清楚,当原对象没有任何强引用的时候,弱引用指针也会被设置为nil。

因此,__block和__weak修饰符的区别其实是挺明显的:
1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3.__block对象可以在block中被重新赋值,__weak不可以。
4.__block对象在ARC下可能会导致循环引用,非ARC下会避免循环引用,__weak只在ARC下使用,可以避免循环引用。

PS:__unsafe_unretained修饰符可以被视为iOS SDK 4.3以前版本的__weak的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。

Blocks理解:

Blocks可以访问局部变量,但是不能修改

如果修改局部变量,需要加__block

__block int multiplier = 7;
     int (^myBlock)(int) = ^(int num) {
         multiplier ++;//这样就可以了
         return num * multiplier;
     };

2、如果局部变量是数组或者指针的时候只复制这个指针,两个指针指向同一个地址,block只修改指针上的内容。如:

NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil];
    NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:1];
    [mArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: ^(id obj,NSUInteger idx, BOOL *stop){
        [mArrayCount addObject:[NSNumber numberWithInt:[obj length]]];
    }];

NSLog(@"%@",mArrayCount);

例子里面确实没有修改mArrayCount这个局部变量啊。mArrayCount是一个指针,指向一个可变长度的数组。在block里面,并没有修改这个指针,而是修改了这个指针指向的数组。换句话说,mArrayCount是一个整数,保存的是一块内存区域的地址,在block里,并没有改变这个地址,而是读取出这个地址,然后去操作这块地址空间的内容。

这是允许的,因为声明block的时候实际上是把当时的临时变量又复制了一份,在block里即使修改了这些复制的变量,也不影响外面的原始变量。即所谓的闭包。

但是当变量是一个指针的时候,block里只是复制了一份这个指针,两个指针指向同一个地址。所以,在block里面对指针指向内容做的修改,在block外面也一样生效。

__weak __typeof(&*self)weakSelf =self; 等同于

__weak UIViewController *weakSelf =self;

为什么不用__block 是因为通过引用来访问self的实例变量 ,self被retain,block也是一个强引用,引起循环引用,用__week是弱引用,当self释放时,weakSelf已经等于nil。

扩展:NSTimer注意避免循环引用的地方,需要找个合适的时机和地方来 invalidate timer

在引用计数的环境里面,默认情况下当你在block里面引用一个Objective-C对象的时候,该对象会被retain。当你简单的引用了一个对象的实例变量时,它同样被retain。但是被__block存储类型修饰符标记的对象变量不会被retain

注意:在垃圾回收机制里面,如果你同时使用__weak和__block来标识一个变量,那么该block将不会保证它是一直是有效的。 如果你在实现方法的时候使用了block,对象的内存管理规则更微妙:也是(__weak与__block区别:)

1、如果你通过引用来访问一个实例变量,self会被retain。
2、如果你通过值来访问一个实例变量,那么变量会被retain

整理如下:__block是强引用类型,__week是弱引用类型。两者相比,__block更加全能,因为它可以在MRC和ARC都可以使用,既能修饰对象又能修饰基本数据类型。但是它还是有缺点,缺点在于在ARC环境下,会引起循环引用。而__week则只能在ARC环境下使用,且只能修饰对象,但是它不会发生循环引用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS开发之 __block 与 __weak的区别理解 的相关文章

随机推荐

  • strongswan——IKE建立过程

    strongswan的主进程为charon进程 负责IKE SA IPSec SA建立 拆除 更新及其他相关的操作 charon进程默认通过socket default插件与内核交互 用于IKE协议报文的收发 socket default插
  • Express全系列教程之(五):Express的中间件

    一 中间件 从字面意思 我们可以了解到它大概就是做中间代理操作 事实也是如此 大多数情况下 中间件就是在做接收到请求和发送响应中间的一系列操作 事实上 express是一个路由和中间件的web框架 Express 应用程序基本上是一系列中间
  • LeetCode-合并两个有序链表(java实现)

    题目如下 看完题目之后 思考的结果是用递归做应该是最佳的选择 但无奈水平真的有限 没有想出来如何用设计递归 提交的时候就没有用递归实现 运行结果可想而知 23ms 看了第一名的用时是5ms 而且代码简洁优美 不得不佩服 Definition
  • Windows2012的VPN服务与测试

    一 配置环境 1 在Windows2012安装VPN服务 勾选网络策略和访问服务与远程访问 2 安装完成后点击打开 选择 打开开始向导 选择配置远程访问的类型 仅部署VPN 3 选择自定义配置后 根据需求选择摘要 VPN需要VPN访问和NA
  • 51单片机数据传送——片外到片内(汇编语言实现)

    51单片机 数据传送 片外到片内 汇编语言实现 问题描述 把存储在片外RAM 1000H开始的16个单元 地址为1000H到100FH 内容依次搬移到片内RAM 30H开始的16个单元 地址为30H到3FH 外部RAM 1000H 100F
  • 数据结构---快速排序

    快速排序 分治法思想 基准元素的选择 元素交换 双边循环法 JAVA实现 单边循环法 JAVA实现 快速排序也是从冒泡排序演化而来 使用了 分治法 快的原因 快速排序和冒泡排序共同点 通过元素之间的比较和交换位置来达到排序的目的 快速排序和
  • elasticsearch-数据聚合

    目录 介绍 实际操作 DSL实现Metrics聚合 嵌套聚合 RestClient实现聚合 以酒店品牌为例 实现对酒店品牌 城市 星级的过滤 补6 20 32条消息 Elasticsearch 聚合查询 aggs 龙源lll的博客 CSDN
  • 成pmo了(几年前帖子,私密变公开后时间就变了)

    哈哈 我还没转正 也没项目 只是做产品 估计就和小学的语文课代表一样
  • border 颜色渐变

    div style border right 1px dashed fff background none width 577px div style font size 16px background color fff div div
  • C语言文本文件与二进制文件转换

    本程序要自己创建个文本格式的输入文件a1 txt 编译后能将文本文件前255字节以内的字符转换成相应的AscII码值的二进制表示 并存入输出文件a2 txt中 然后再将二进制文件还原并存入a3 txt文件 实现文件之间的转换 具体代码如下
  • vue项目cdn加速,减少webpack打包体积

    在webpack中使用cdn加速优化 减少打包体积 减少用户访问时间 文章目录 在webpack中使用cdn加速优化 减少打包体积 减少用户访问时间 1 引入cdn资源 2 在webpack基础配置文件中加入externals配置 打包 编
  • Java动态追踪技术探究

    Java动态追踪技术是指在Java应用程序运行过程中 通过监控和记录方法调用 异常 性能指标等信息 以便于分析和排查问题 优化性能 或进行安全审计等目的的技术手段 在Java开发和运维中 动态追踪技术起到了重要的作用 能够帮助开发人员和运维
  • idea中maven找不到本地仓库jar包_Maven 的这 7 个问题你思考过没有?

    专注于Java领域优质技术 欢迎关注 作者 张丰哲 在如今的互联网项目开发当中 特别是Java领域 可以说Maven随处可见 Maven的仓库管理 依赖管理 继承和聚合等特性为项目的构建提供了一整套完善的解决方案 可以说如果你搞不懂Mave
  • 自我理解:精度(precision)和召回(recall)

    1 精度 precision 精度是用于评估分类模型的一个重要指标 它反映了模型预测为正例的样本中 实际真正为正例样本的比例 注 正例样本指在二分类问题中 被标注为正类的样本 例如 在垃圾邮件分类任务中 正例样本就是真实的垃圾邮件 精度的计
  • 大学生团体天梯赛(第三届)

    题目地址 天梯赛 include
  • 树莓派LINUX内核移植

    参考博文 https editor csdn net md not checkout 1 articleId 109006969 树莓派linux内核下载地址 https github com raspberryPi 需要下载内核的版本可以
  • Hadoop的搭建,VmwareWorkstation 16pro + Ubuntu18.04.1

    文章目录 前言 一 VmwareWorkstation 16pro安装Ubuntu18 04 1 二 Ubuntu的基础配置 1 设置国内镜像源 2 下载安装Vmware Tools 三 安装Hadoop 总结 前言 Hadoop的搭建过程
  • PyQt编程实战:画出QScrollArea的scrollAreaWidgetContents内容部署层的范围矩形

    老猿Python博文目录 专栏 使用PyQt开发图形界面Python应用 老猿Python博客地址 一 引言 在 PyQt Python Qt 学习随笔 QScrollArea滚动区域详解 介绍了滚动区域的展现层 也称框架层 和内容部署层
  • python的格式化输出

    python格式化输出 被称为格式化操作符 专门用于处理字符串中的格式 包含 的字符串 被称为格式化字符串 和不同的字符串连用 不同类型的数据 需要使用不同的格式化字符 格式化字符 含义 s 字符串 d 有符号十进制整数 06d不是输出的整
  • iOS开发之 __block 与 __weak的区别理解

    资料来源1 资料来源2 block对象在block中是可以被修改 重新赋值的 使用了 weak修饰符的对象 作用等同于定义为weak的property 自然不会导致循环引用问题 因为苹果文档已经说的很清楚 当原对象没有任何强引用的时候 弱引