block 的数据结构定义以下(图片来自 这里):数据结构
对应的结构体定义以下:ide
struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(void *dst, void *src); void (*dispose)(void *); }; struct Block_layout { void *isa; int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor *descriptor; /* Imported variables. */}; |
|
isa 指针,全部对象都有该指针,用于实现对象相关的功能。函数
flags,用于按 bit 位表示一些 block 的附加信息,本文后面介绍 block copy 的实现代码能够看到对该变量的使用。spa
reserved,保留变量。指针
invoke,函数指针,指向具体的 block 实现的函数调用地址。code
descriptor, 表示该 block 的附加描述信息,主要是 size 大小,以及 copy 和 dispose 函数的指针。orm
variables,capture 过来的变量,block 可以访问它外部的局部变量,就是由于将这些变量(或变量的地址)复制到告终构体中。对象
该数据结构和后面的 clang 分析出来的结构实际是同样的,不过仅是结构体的嵌套方式不同。但这一点我一开始没有想明白,因此也给你们解释一下,以下 2 个结构体 SampleA 和 SampleB 在内存上是彻底同样的,缘由是结构体自己并不带有任何额外的附加信息。图片
struct SampleA { int a; int b; int c; }; struct SampleB { int a; struct Part1 { int b; }; struct Part2 { int c; }; }; |
在 Objective-C 语言中,一共有 3 种类型的 block:ip
_NSConcreteGlobalBlock 全局的静态 block,不会访问任何外部变量。
_NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。
_NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。