Block相关

208 阅读1分钟

Block

block的原理是什么 本质是什么

本质是一个 oc 对象, 内部也有一个 isa 指针
内部封装了 block 执行逻辑的函数

Block 的本质

结构体对象

int age = 20;
void (^block) (void) = ^ {
	NSLog(@"age is %d", age);
};

变量自动捕获👇

struct __main_block_impl_0 {
	struct __block_impl impl; //impl 结构体见👇
	struct __main_block_desc_0* Desc;
	int age;// 自动变量捕获
}
struct __block_impl {
	void *isa;
	int Flags;
	int Reserved;
	void *FuncPtr; //指向 block 内部实现的函数地址 (见👇)
}
// 封装了 block 执行逻辑的函数
static void __main_block_func_0 () {
	//TODO
}

变量捕获

标题是否捕获捕获方式
auto变量捕获值传递
static捕获--
全局变量不捕获直接访问

局部变量需要捕获是因为需要跨函数访问

Block 类型

继承自NSBlock类型

globleBlock 没有访问 auto 变量 (访问 static 和 全局变量仍让是 globelBlock)

stackBlock 访问了 auto 变量 (MRC 下能打印出来, ARC下会自动调动 copy ---> mallocBlock)

mallocBlock ----> stackBlock 调用了 copy (栈 --- > 堆上)  

__block的作用

__block 可解决 block 内部无法修改 auto 变量的问题 

编译器会将__block变量包装成一个对象 __Block_byref_xxx_0

基本数据类型 int age = 0; 编译器会将 age 包装成 __Block_byref_age_0 结构体

1.__main_block_impl_0 结构体内持有  __Block_byref_age_0
2.__Block_byref_age_0 内部持有 __forwarding 指针指向自己

Block 内存管理

当 block 被 copy 到堆上时,会调用block内部的 copy 函数,copy 函数会调用 __Block_object_assign