摘要 引用自http://blog.itanbing.com/2015/07/20/block-retain-cycle-problem/
block是2010年WWDC苹果为Objective-C提供的一个新特性,它为我们开发提供了便利,比如GCD就大量使用了block,用来往执行队列中添加执行。那么block到底是什么东西呢。其实它就是一个闭包,一个引用自动变量的函数。很多语言也实现自己的闭包,比如C#的lamda表达式。这篇文章将从分析源码的角度来分析下block到底是什么鬼。
最简单的block,不持有变量
我们先新建一个源文件:block.c 代码如下
#include <stdio.h>int main(){
void (^blk)(void) = ^(){printf("This is a block.");};
blk();
return 0;
}
我们使用clang(LLVM编译器,和GCC类似),通过命令clang -rewrite-objc block.c
,解析block.c这样我们就会得到对应的cpp文件block.cpp。去除一些影响我们阅读的代码。如下:
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__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;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
printf("This is a block.");
}
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
int 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);
return 0;
}