关于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混编.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容