概念:
block本质也是一个OC对象,内部也有isa指针。
block封装了函数调用。
底层数据结构:
将下面这句代码转成底层c++实现
int age = 10;
void (^block)(void) = ^{
NSLog(@"age is %d",age);
};
block();
- 切换到目标文件的上级目录
- 终端命令为 将x换为需要转换的目标文件
clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk x
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
};
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *Funcptr;
}
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
}
对下面这段代码进行解读
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *Funcptr;
}
isa:指向所属类的指针,也就是block类型
flags:标志变量,在实现block的内部操作时会用到
block的类型
- 堆block:堆内存,程序员手动管理
- 栈block:栈内存,随时会被系统回收,对应的栈block同样会被随时回收
使用copy修饰,将栈block复制到堆上。
- 全局block:不引用外部变量,或者引用静态变量和全局变量
block的捕获
值类型捕获、引用类型
局部变量,全局变量、
捕获的流程,
——block的使用
block内部修改auto变量的值,无法直接修改,就需要用到__block修饰符。此修饰符无法修饰static以及全局变量
被__block修饰的变量会被包装我结构体对象,结构体中有此变量,有此变量的地址
Block问答题
1、如何区分block类型
- Block不会捕获全局变量,但是局部变量需要捕获?
全局变量在任何时候任何地方都可以访问,因此不需要捕获,局部变量因为作用域的问题,需要捕获,保证block内部能访问到该变量
- 使用copy修饰block,内部做了什么?
copy函数内部会调用
Block_object_assign
函数,此函数会根据auto变量的修饰符(__strong、__weak、__unsafe-unretained)做出相应的操作,类似于retain(形成强引用,弱引用)
网友评论