- 这次【Block系列】学习的内容比较难,基础不是很扎实的同学,希望可以和我一样,花多一点时间慢慢理解。
- 我认为我的注释还是比较详细的,如果不理解的地方欢迎一起交流、留言。
1、基本使用
- (void)testBlock {// 方式一^{NSLog(@"--直接调用block块");}();// 方式二void (^block)(void) = ^{NSLog(@"--block");};block();// 带参数int (^block1)(int, int) = ^(int a,int b){NSLog(@"--block--%d",a + b);int c = a * b;NSLog(@"c--%d",c);return c;};block1(1,2);
}// 打印
2021-12-30 20:49:27.638055+0800 02-kvc[24397:316340] --直接调用block块
2021-12-30 20:49:27.638161+0800 02-kvc[24397:316340] --block
2021-12-30 20:49:27.638234+0800 02-kvc[24397:316340] --block--3
2021-12-30 20:49:27.638308+0800 02-kvc[24397:316340] c--2
- block的本质上也是OC对象,它内部有个isa指针
- block是封装了函数调用以及函数调用环境的OC对象
- block的底层结构
- 转换成c++代码方式请看 [这里]
// 把以上代码转成c++代码 ,只看单参数的那部分代码
// part 1
struct __block_impl {void *isa;int Flags;int Reserved;void *FuncPtr;
};// part 2
struct __ViewController__testBlock_block_impl_2 {struct __block_impl impl;struct __ViewController__testBlock_block_desc_2* Desc;int age;__ViewController__testBlock_block_impl_2(void *fp, struct __ViewController__testBlock_block_desc_2 *desc, int _age, int flags=0) : age(_age) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}
};
// part 3
static int __ViewController__testBlock_block_func_2(struct __ViewController__testBlock_block_impl_2 *__cself, int a, int b) {int age = __cself->age; // bound by copyNSLog((NSString *)&__NSConstantStringImpl__var_folders_yt_xssy0rbn7v9bq55cfc22sd4w0000gn_T_ViewController_9a30a7_mi_2,age);int c = a * b;NSLog((NSString *)&__NSConstantStringImpl__var_folders_yt_xssy0rbn7v9bq55cfc22sd4w0000gn_T_ViewController_9a30a7_mi_3,c);return c;}// part 4
static struct __ViewController__testBlock_block_desc_2 {size_t reserved;size_t Block_size;
} __ViewController__testBlock_block_desc_2_DATA = { 0, sizeof(struct __ViewController__testBlock_block_impl_2)};
- 可能看起来有点复杂,但是稍微简化一下,只看impl(实现)部分
- 底层结构如下所示:
struct __ViewController__testBlock_block_impl_2 {void *isa;int Flags;int Reserved;void *FuncPtr;struct __ViewController__testBlock_block_desc_2* Desc;int age;__ViewController__testBlock_block_impl_2(void *fp, struct __ViewController__testBlock_block_desc_2 *desc, int _age, int flags=0) : age(_age) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}
};