教育网站建设网站建设客户

上海顾湘里品牌管理有限公司 2026/09/09 19:01:55

[iOS原理] Block的本质

文章目录

  • [iOS原理] Block的本质
  • 前置研究
    • iOS内存五大分区
      • 栈区
      • 堆区
      • 全局区 / 静态区
      • 常量区
      • 代码区
    • isa指针
  • Block
      • Block的本质
      • Block的三种类型
      • __block的本质
    • ARC 在某些情况下会对 block 自动进行一次 copy 操作,将其从栈区移动到堆区
    • Block的应用及其注意事项

“心理史学……盖尔·多尼克将其定义为数学的一个分支,专门处理人类群体对特定的社会与经济刺激所产生的反应……”

“在这门学科的定义中,隐含着一个假设,即作为研究对象的人类汇集必须大到足以用统计学的方法来处理。集结的人数由许许多多的‘阿西莫夫系数’(Asimov coefficient)决定。群体越大,预测的准确性就越高。”

——摘自《银河百科全书》第116版

上一篇博客里我们简单讲解了Block的用法,这篇里,我们来讲解一下Block的本质及其实现

在讲本质之前,我们先来复习(学习)几个前置概念

前置研究

iOS内存五大分区

iOS内存我们之前有讲过底层的分配逻辑,我们现在来讲讲它的内存布局

内存分区分为

  • 栈区
  • 堆区
  • 全局区 / 静态区
  • 常量区
  • 代码区

想要判断一块数据在哪一部分,只需要使用lldb指令frame variable -L来查看即可

栈区

栈区内存由系统自动分配和释放,不需要我们操心,它的存取速度极快

一般来说,负责存放函数的参数和函数内部定义的局部变量

堆区

内存由程序员手动管理

ARC时代,虽然编译器帮我们插入了retain/release,但本质上还是需要管理的(笑)

如果处理不好,出现野指针或者内存泄露就不好了

速度相对栈区要慢,一般存放通过alloc,new,copy,mutableCopy等创建的对象

全局区 / 静态区

全局区 / 静态区部分,程序运行期间一直存在,直到App退出才会被释放

它分为BSS(未初始化)和Data(已初始化)部分

一般来说存放全局变量和静态变量

常量区

常量区的数据只读,不可被修改,一般存放常量字符串,(如@"Hello"),或者const修饰的全局变量

一旦编译完成,其中的内容就无法再修改了

代码区

代码区跟上面比起来更像是规则而不是数据,它同样可读不可写

它里面存放的东西是编译之后的二进制代码

isa指针

isa指针可以说是 Objective-C Runtime(运行时)机制的关键部分

简单来说,它是一张身份证,上面记载了所属对象的类别和其他信息

它告诉系统,我是谁,属于什么类

最关键的一点在于,isa构成了oc中查找方法的路径

对于block的原理来讲,我们现在先只复习这么多就足够了

Block

Block的本质

Block有的时候我们说可以把它的返回类型当作它的类型来用,有的时候说它是一种函数

我们使用clang指令将oc转换为C++可以看出

// Block 的底层结构体struct__main_block_impl_0{struct__block_impl impl;// block 的基本信息(包含 isa)struct__main_block_desc_0*Desc;// 描述信息(大小等)intage;// 捕获的外部变量// 构造函数__main_block_impl_0(void*fp,struct__main_block_desc_0*desc,int_age,intflags=0):age(_age){impl.isa=&_NSConcreteStackBlock;// isa 指针impl.FuncPtr=fp;// 函数指针,指向具体执行的代码// ...}};

Block是有isa指针的,即它是一个对象

再观察覆写出的C++代码,找到其中的FuncPtr

编译器会把 Block 花括号{ ... }里的代码提取出来,封装成一个静态 C 函数,然后让FuncPtr指向这个函数。调用 Block,本质上就是通过函数指针调用这个 C 函数

那关于捕获外部变量,Block又是如何实现的呢

继续观察覆写代码,结构体里的int age;即为Block捕获的外部变量

当你定义 Block 时,它把外部的age变量的值拷贝到了自己的结构体里,之后无论外面的age怎么变,Block 结构体里的age依然是 10

Block的三种类型

Block作为对象,在内存中也有位置,根据它的位置不同,Block分为三种:

  • _NSConcreteGlobalBlock(全局 Block)
    • 位置:数据区(Data段)。
    • 特点:没有访问任何外部局部变量(或者只访问了全局变量/静态变量)。相当于一个单例,整个 App 生命周期都在
  • _NSConcreteStackBlock(栈 Block)
    • 位置:栈区。
    • 特点:访问了外部局部变量。这是最危险的,因为栈内存由系统自动释放。如果作用域结束,Block 就没了,再调用就会 Crash
    • 注意:在 ARC 环境下,编译器会自动帮我们将栈 Block 拷贝到堆上,所以我们现在很少见到纯粹的栈 Block 了
  • _NSConcreteMallocBlock(堆 Block)
    • 位置:堆区。
    • 特点:由栈 Block 调用copy而来。它的生命周期由引用计数管理(我们现在的 Block 属性都用copy修饰,就是为了把它搬到堆上,防止被销毁)

__block的本质

之前讲过,直接在block里修改外部局部变量会报错,必须加入__block修饰符

在默认情况下,Block捕获的是变量的值,是只读的

在加入__block后,编译器会生成一个新的结构体对象,并把原来的值变量将入到这个对象里

这样,它的本质是将值传递,变成指针传递

ARC 在某些情况下会对 block 自动进行一次 copy 操作,将其从栈区移动到堆区

出现以下情况时,ARC会自动对block执行一次copy操作,将其从栈区移动到堆区:

  1. block作为函数返回值时
  2. block被强指针引用时
  3. 当 Cocoa API 方法名包含usingBlock,且block作为参数时,或block作为GCD API方法参数

Block的应用及其注意事项

作为iOS开发人员,对Block的使用一定是要达到精通程度的

Block的应用场景很广,首先就是函数思想,利用它作为一个匿名函数的性质,来保存代码块,灵活操作

但在架构层次中,如果你的嵌套层次非常深,那么不要使用Block,因为在这种情况下,Block的大量使用不便与你的代码调试以及代码直观性

引用资料:

  1. iOS开发—Block底层详解
  2. Cocoa blocks as strong pointers vs copy
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

免费企业网站建设建设摩托车官方网站

图像编码器微调:CLIP ViT结构适配新领域在医学影像分析的日常工作中,医生常常需要从一张肺部X光片中判断是否存在肺炎迹象,并生成结构化的诊断报告。传统流程

2026/06/30 13:46:07

苏州网站建设网站建设论文

界面新闻财经内容检查:Qwen3Guard-Gen-8B识别市场操纵言论在信息传播速度远超监管反应节奏的今天,一条看似普通的财经评论,可能正悄然撬动千万级资金

2026/06/30 13:24:35

诸城网站建设马鞍山网站建设

智能家居DIY:用RAM模型给你的家装上"眼睛"想让你的智能家居系统像人类一样识别家庭成员和日常物品吗?RAM(Recognize Anyth

2026/06/30 10:30:20

寿光网站建设网站建设优化

一对一咨询预约:让销售团队直接对接高意向用户在AI模型服务和智能硬件这类技术密集型行业中,一个常见的尴尬局面是:潜在客户明明表现出浓厚兴趣——反复浏览技术文档

2026/06/30 14:16:39

成都网站建设孝感网站建设

迈向 6G 移动通信的深度学习与联邦学习1. 机器学习与深度学习概述随着机器学习(ML)和人工智能(AI)的飞速发展,将 ML 应用于无线通信系统和网络的优化,成为了超越第五代(5G)和第六代(6G)

2026/06/30 13:00:34

南京网站建设海淀网站建设

快速体验打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容:开发一个交互式foreach学习工具,包含:1)

2026/06/30 10:36:51

app网站建设山东网站建设

i2s音频接口如何撑起多通道录音?从原理到实战的深度拆解你有没有遇到过这样的问题:想做一个四麦阵列做语音唤醒,结果发现主控的i2s只支持立体声;

2026/06/30 13:48:07

贵阳网站建设网站建设计划书

硬盘隐藏区域及安全功能的访问与管理1. 硬盘SMART日志相关信息硬盘存在一些特定的SMART日志代码,不同代码代表不同的含义,如下表所示:| 代码 | 数量 | 其他信息 | 含义 || — | —

2026/06/30 11:33:26

青岛网站建设公司物流网站建设

YOLOFuse 国内镜像源推荐:突破访问壁垒,高效开展多模态目标检测在智能安防、自动驾驶和夜间巡检等前沿领域,单一视觉模态的局限性日益凸显。低光照环境下可见

2026/06/30 13:08:34

网站建设流程图网站建设班

一、反射1. 反射获取构造方法在Java中,反射获取构造方法是实现动态创建对象的关键技术。它使程序能够在运行时:动态加载未知类突破私有访问限制(如私有构造方法

2026/06/30 12:27:01