结论:Block的本质是结构体。
验证过程
1.C++转码
在viewDidLoad初始化一个Block,并且调用如下:
void(^block)(void) = ^{
NSLog(@"block----");
};
block();
将Block代码所在文件转成
C++
代码。
注:cd 你当前项目文件夹 -> xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc Block所在的文件 —> 回车
-
生成如下文件
导入项目中,因为默认Xcode是不支持编译
C++
文件的,尝试编译会报一堆红
点击
Build Phases
->Compile Sources
-> 删除导入的cpp文件 不参与编译
2.查看C++代码中OC Block初始化和调用部分。
search - > viewDidLoad 关键字
static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("ViewController"))}, sel_registerName("viewDidLoad"));
//声明
void(*block)(void) = ((void (*)())&__ViewController__viewDidLoad_block_impl_0((void *)__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA));
//调用
((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
}
- 简化一下去掉不必要的强制转化
//声明
void(*block)(void) = &__ViewController__viewDidLoad_block_impl_0(__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA));
//调用
block->FuncPtr(block);
分析 : block->FuncPtr指向的函数地址然后调用
分析 : __ViewController__viewDidLoad_block_impl_0 search
struct __ViewController__viewDidLoad_block_impl_0 {
struct __block_impl impl;
struct __ViewController__viewDidLoad_block_desc_0* Desc;
//构造函数 - > 类似OC init 返回结构体
__ViewController__viewDidLoad_block_impl_0(void *fp, struct __ViewController__viewDidLoad_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
这种函数称之为构造函数类似于OC
init
初始化方法。构造函数返回的是结构体对象。结构体的地址赋值给了Block。
所以Block的本质是结构体。
C++
Block声明调用完整源码
struct __ViewController__viewDidLoad_block_impl_0 {
struct __block_impl impl;
struct __ViewController__viewDidLoad_block_desc_0* Desc;
//构造函数 - > 类似OC init 返回结构体
__ViewController__viewDidLoad_block_impl_0(void *fp, struct __ViewController__viewDidLoad_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
//Block 执行内部的逻辑函数
static void __ViewController__viewDidLoad_block_func_0(struct __ViewController__viewDidLoad_block_impl_0 *__cself) {
//打印 内容 block---
NSLog((NSString *)&__NSConstantStringImpl__var_folders_1y__lhqj8pj6qx60xxbtx_r1z6w0000gn_T_ViewController_7b9f5e_mi_0);
}
static struct __ViewController__viewDidLoad_block_desc_0 {
size_t reserved;
size_t Block_size;
} __ViewController__viewDidLoad_block_desc_0_DATA = { 0, sizeof(struct __ViewController__viewDidLoad_block_impl_0)};
static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("ViewController"))}, sel_registerName("viewDidLoad"));
//声明
void(*block)(void) = ((void (*)())&__ViewController__viewDidLoad_block_impl_0((void *)__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA));
//调用
((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
}