Block的底层实现(一):无截获变量Block

Blocks用一句话概括就是带有自动变量的匿名函数.

首先先创建一个简单的无参数无返回值的block。

int main(){

void (^blk)(void) = ^{

printf("Block\n");

};

blk();

return 0;

}

在main函数中创建一个简单的block,block中是一个简单的printf;

然后通过clang(LLVM编译器)转换为我们可读源代码的功能;

通过命令clang -rewrite-objc 源代码文件名

然后获得了转换后的Block语法。

转换后的源代码文件有数百行的代码,不用管其他,我们只需要翻到文件的最下边,也就是下图中的位置:

Block的底层实现(一):无截获变量Block_第1张图片

block编译后的代码.png

首先,先寻找到源代码中block的位置,也就是main函数所在的位置,图中可以清晰的看到,然后来看main函数中的代码:

编译后的代码:

void (*blk)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);

接着我们来简化一下,去掉转换的部分,具体如下:

struct __main_block_impl_0 tmp = __main_block_impl_0(__main_block_func_0,&__main_block_desc_0_DATA);

struct __main_block_impl_0 blk = &tmp;

这段代码等于__main_block_impl_0结构体实例的指针变量赋给变量blk,

也就是说源代码中的Block就是__main_block_impl_0结构体指针产生的自动变量。

接下里看一下这段代码:

__main_block_impl_0(__main_block_func_0,&__main_block_desc_0_DATA);

第一个参数是由Block语法转换的的C语言函数指针,第二个参数是作为静态全局变量初始化的__main_block_desc_0的结构体指针。

首先看第一个参数的这个函数指针:

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

printf("Block\n");

}

通过这段代码可以看出,Blocks使用的匿名函数实际上被作为了简单的C语言函数来处理了;

然后看一下传的参数struct __main_block_impl_0 *__cself;

这个__main_block_impl_0结构体的指针__cself相当于Objectice-C中的self;

然后是struct  __main_block_impl_0这个结构体的声明,如下:

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

}

然后分别看一看其中的结构体,首先是第一个成员变量impl,来看一下__block_impl结构体的声明。

struct  __block_impl{

void * isa;

int Flags;

int Reserved;

void * FucnPtr;

};

从其名称可以看出某些标志、今后版本升级所需的区域以及函数指针。

然后是__main_block_desc_0结构体的声明;

static struct __main_block_desc_0{

size_t reserved;

size_t Block_sized;

};

这些也如同其成员名称所示,其结构为今后版本升级所需区域和block的大小。

接下来就要看一看初始化含有这些结构体的__main_block_impl_0结构体的构造函数。

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

以上就是无变量截获无返回值的block初始化的源代码。

你可能感兴趣的:(Block的底层实现(一):无截获变量Block)