1. 在OC中block的声明->赋值->使用
int main(int argc, const char * argv[]) {
@autoreleasepool {
声明:
void (^block)(int count);
返回值 变量名 参数
赋值:
返回值 参数 {要执行的代码}
block = ^void(int count) {
count++;
NSLog(@"count=%d, 地址:%p", count, &count);
};
使用:
变量名(参数);
block(count);
}
}
2. block的底层实现
在cmd中进入到当前文件所在目录,利用clang(LLVM编译器),将OC代码转换成C/C++代码;
clang -rewrite-objc main.m
会在同级目录下生成一个main.cpp的文件,在其中我们就能找到我们需要的代码;
主要包含了以下3个结构体和1个函数以及main函数的实现,在main函数中我们就能分析OC的block在底层的实现
struct __block_impl {
void *isa; // 指向_NSConcreteStackBlock/NSConCreteMallocBlock/NSConCreteGlobleBlock类创建的实例
int Flags; // 标识符
int Reserved; // 保留字段
void *FuncPtr; // block{}中函数实现的函数指针
};
static struct __main_block_desc_0 {
size_t reserved; // 保留字段
size_t Block_size; // 表示该结构体占据多少孔家
};
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0 *Desc;
// 初始化
// fp: 是block{}中的代码实现
// desc: 是block的描述信息(所占用的内存空间大小)
// flags: 标识符
__main_block_impl_0(void *fp, struct __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, int count) {
count++;
NSLog((NSString *)&__NSConstantStringImpl__var_folders_7x_02rxw4ms63z1hyly7yn3nj040000gn_T_main_672f2f_mi_0, count, &count);
};
int main(int argc, const char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
// 声明 一个C语言的指针变量
void (*block)(int count);
int count = 10;
// 赋值 创建__main_block_impl_0结构体 调用__main_block_impl_0的函数进行初始化,并进行强制类型转换,转换为 (void (*)(int))即C语言的函数指针
block = ((void (*)(int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
// 调用,实际是执行了__main_block_func_0函数
((void (*)(__block_impl *, int))((__block_impl *)block)->FuncPtr)((__block_impl *)block, count);
NSLog((NSString *)&__NSConstantStringImpl__var_folders_7x_02rxw4ms63z1hyly7yn3nj040000gn_T_main_672f2f_mi_1, count, &count);
}
return 0;
}
3. 总结
block实际就是C语言的函数指针,只是用3个结构体来表示OC对象
所以表面上来看block是一个匿名函数,实际上在底层它还是有函数名称的
声明:参考文章https://juejin.im/post/5cc0050cf265da035948746d
网友评论