1. Block是将函数及其执行上下文封装起来的对象
Block在编译后的函数体是一个c函数,在调用时直接通过指针调用。
struct Block_layout {
void *isa;
int32_t flags; //引用计数
int32_t reserved;
void *invoke; //函数指针
struct Block_descriptor1 *descriptor;
};
struct Blcok_descriptor1{
uintptr_t reserved;
uintptr_t size;
}
2. 截获变量
{
int multi = 6;
void (^Block)(int) = ^int(int num) {
return num *multi;
}
multi = 4;
NSLog(@"result is %d", Block(2));
}
- 局部变量
- 基本数据类型: 截获其值
- 对象类型:连同所有权修饰符一起截获
- 静态局部变量:以指针形式截获
- 全局变量:不截获
- 静态全局变量:不截获
3. __block修饰符
一般情况下,对被截获变量进行赋值操作需要使用__block修饰符
NSMutableArray *arr = [NSMutableArray array];
void(^block)(void) = ^{
[arr addobject:@1];
};
__block NSMutableArray *arr = [NSMutableArray array];
void(^block)(void) = ^{
arr = [NSMutableArray array];
}
静态局部变量、全局变量、静态全局变量不涉及截获操作,不需要__block修饰符
__block修饰的变量变成了对象
struct _Block_byref_multiplier_0 {
void *__isa;
__Block_byref_multipiler_0 *__forwarding;
int __flags;
int __size;
int multipiler;
}
栈上的__forwarding指向自身