关于block

1.block不调用外界变量的情况

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event { //类型变量名=值; intage = 100; NSLog(@"====%p",&age);栈区 //没有参数没有返回值的block void(^block)() = ^{ NSLog(@"我是block = %p",&age);堆区 }; //执行block block(); [selftestBlock:block]; NSLog(@"====%p",&age);栈区 }
- (void)testBlock:(void(^)())block { block(); }

2.通过__block调用外部变量的情况

总结:只要通过__block修饰以后,外部变量的地址就变为堆区,在调用blcok之前值还是栈区的值,而地址在堆区,当调用了block以后,值变为修改后的值,而地址也在堆区

/**
* block修改外部变量
*/
- (void)testBlock5 { //类型变量名=值; __block intage = 100; NSLog(@"====%p",&age);//栈 //使用__block修饰外部变量时,在定义完成block之后,栈中的外部变量就是一个摆设,没有什么乱用了 void(^block)() = ^{ age = 200; NSLog(@"block中的age = %d",age);// 200 NSLog(@"我是block = %p",&age);//堆 };

使用__block修饰以后,但是没有调用block时候,值不改变,但是地址保存到堆区了

NSLog(@"====%p",&age);//堆 NSLog(@"age =%d",age);// 100 //执行block //使用__block修饰以后,调用了block以后,值改变,地址也保存到堆区了, block(); NSLog(@"====%p",&age);//堆 NSLog(@"age =%d",age);// 200 }

**结语: **

1.block的三种类型:

全局block :(打印出来__NSGlobalBlock)

---无论是ARC还是MRC情况下:block内部没有访问任何外部变量时,block就是全局block

---或者访问的是static修饰的静态变量的时候,就是全局block

堆block: (打印出来是__NSMallocBlock)block内部访问我外部变量时,(不为静态变量时,).block是堆区block
---在MRC环境下,给block调用copy方法,会将栈block拷贝到堆中

C.栈block :(打印出来是__NSStackBlock)

---在MRC情况下,block内部访问外部变量时(不为静态变量),block是栈区block

为什么block要用copy修饰,因为不用copy修饰,当MRC模式 下,block内部访问外部属性时(且属性不为静态属性时),block是栈区block,这样外界调用的时候,就会报错,使用copy,我们的block无论是ARC还是MRC情况下,肯定是堆区block,外界调用就不会有影响

所以block使用copy是为了兼容MRC的情况,因为很多项目是ARC和MRC混编.

你可能感兴趣的:(关于block)