1、写一个简单的mac命令行程序,包含block定义与使用
1 2 3 4 5 6 7 8 9 10 11 | #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { void (^block)(void) = ^{ NSLog(@"Hello block!"); }; block(); } return 0; } |
2、在命令行下编译成c++源文件xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m
3、得到的cpp文件有3万多行,找到尾部的main函数,与block相关的代码有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // 1、block定义,结构体__main_block_impl_0 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; } }; // 2.1、block体__main_block_func_0将做为参数传入block构造函数,__main_block_impl_0第一个参数 static void __main_block_func_0(struct __main_block_impl_0 *__cself) { // block内部代码 } // 2.2、__main_block_impl_0构造函数第二个参数,__main_block_desc_0 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)}; /* 3、调用 block = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA); block->FuncPtr(block); */ void (*block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA)); ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block); |
4、总结:block本质是OC对象,block体等价于对象方法,在block体执行时会调用该方法;
1、block中如果涉及到参数,在生成block对象中,block体执行函数会增加相对应的参数传递
2、相关block对象中的执行函数
1、block中如果涉及到外部变量,在生成block对象时会新增相应的成员变量
2、相对应的block结构体是这样的