什么是block?

block是将函数及其执行上下文封装起来的对象

Block 截获变量

请看下面一段代码执行之后的打印结果是多少?

局部变量

int number = 6;

int(^Block)(int) = ^int(int num){

     return num * number;

};

number = 4;

NSLog(@"result is %d",Block(2));

正确答案是 : 12

带修饰符

__strong id strong_obj

__unsafe_unretained id unsafe_obj;

全局变量

@property (nonatomic, assign) int number1;

self.number1 = 10;

int(^Block1)(int) = ^int(int num){

    return num * self.number1;

};

self.number1 = 4;

NSLog(@"result2 is %d",Block1(2));

正确答案是 : 8

全局的静态变量

static int number2 = 10;

number2 = 3;

int(^Block2)(int) = ^int(int num){

    return num * number2;

};

number2 = 5;

NSLog(@"result3 is %d",Block2(2));

正确答案是 : 10

对于基本数据类型的局部变量截获其值

对于对象类型的局部变量连同所有权修饰符一起截获

以指针形式截获局部静态变量

不截获全局变量、静态全局变量

__block修饰符

一般情况下,对呗截获变量进行赋值操作需添加_block修饰符

NSMutableArray *array = [NSMutableArray array];

void(^Block4)(void) = ^{

    [array addObject:@123];

};

Block4();

NSLog(@"result5 is %@",array);

__block  NSMutableArray *array1 = [NSMutableArray array];

void(^Block5)(void) = ^{

    array1 = [NSMutableArray array];

};

Block5();

NSLog(@"result6 is %@",array1);

对变量进行赋值时

不需要_blcok修饰符

  1. 静态局部变量

  2. 全局变量

  3. 静态全局变量

需要用_block修饰的是局部变量

__block int number3 = 6;

int(^Block6)(int) = ^int(int num){

    return num * number3;

};

number3 = 4;

NSLog(@"result7 is %d",Block6(2));

正确答案是 : 8

如果不用_block修饰则会打印12

__block修饰的变量变成了对象

它里面包含了一个完整的机构体

block为什么要进行copy操作?

621206f0e56d9.png

block对象结构体里面的forwardig存在的意义

不论存在任何位置 都可以统一的访问同一个_block变量

Block循环引用

自循环引用

block捕获的成员变量也是当前对象中的成员变量 而block又存在当前对象中 _weak避免循环引用 或者断链 置空nil,给强持有对象赋值为原对象

相互循环引用

互相指向

多循环引用

多个对象指向形成一个环形的链式引用

如果破除循环引用?

  1. 避免产生循环引用

  2. 合适的时机手动断环