什么是block:block是将函数及其上下文封装起来的对象
什么是block调用:block调用即是函数的调用
终端命令 clang -rewrite-objc fileName.m 生成 fileName.cpp
终端命令 clang -rewrite-objc -fobjc-arc fileName.m 生成 fileName.cpp 截取变量
一般情况下,对被截获变量进行赋值需要添加__block修饰符
为什么block会产生循环引用
block对当前对象进行截获会对当前对象强引用,而当前对象对block又有一个强引用,所以自循环。通过__weak来解除
__block MRC下不会 ARC下会循环引用,段环的方式来消除,但是如果该block一直没有调用,就不会释放
代码示例
image.png
int global_var = 4;
static int static_global_var = 5;
-- (void)method
{
int var = 10;
__unsafe_unretained id unsafe_obj = nil;
__strong id strong_obj = nil;
int * static_var
static int multiplier = 6;
int(^Block)(int) = ^int(int num)
{
NSLog(@"var %d",var);
NSLog(@"unsafe_obj %@",unsafe_obj);
NSLog(@"strong_obj %@",strong_obj);
NSLog(@"multiplier %d",multiplier);
//NSLog(@"static_var %d",static_var);
NSLog(@"global_var %d",global_var);
NSLog(@"static_global_var %d",static_global_var);
return num * multiplier;
};
multiplier = 4;
NSLog(@"result is %d", Block(2));
打印结果: //var 10// unsafe_obj (null)//strong_obj (null)//multiplier 4//global_var 4//static_global_var 5//result is 8
int i = 10;
static int m = 100;
NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
void (^blk)(void) = ^{
NSLog(@"In block, i = %d", i);
NSLog(@"In block, m = %d", m);
for (NSString *str in mArray) {
NSLog(@"In block, str = %@", str);
}
};
i = 20;
m = 200;
[mArray addObject:@"3"];
blk();
打印结果: //i = 10//m = 200//str = 1//str = 2//str = 3
}
一般情况下,对截获变量进行赋值操作需添加__block修饰符
赋值不等于使用,赋值需要,使用不需要!
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
__forwarding存在的意义:不论在任何内存位置,都可以顺利访问同一个_block变量
循环引用
image.png
image.png