您的位置:首页 > 其它

OC之 block 本质

2016-01-07 00:00 302 查看

实现方式

数据结构定义

block 的数据结构定义如下(图片来自 这里):



对应的结构体定义如下:
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 的实现代码可以看到对该变量的使用。

reserved,保留变量。

invoke,函数指针,指向具体的 block 实现的函数调用地址。

descriptor, 表示该 block 的附加描述信息,主要是 size 大小,以及 copy 和 dispose 函数的指针。

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:

_NSConcreteGlobalBlock 全局的静态 block,不会访问任何外部变量。

_NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。

_NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: