为什么在block内部修改局部变量要加__block???

之前学习block的时候告诉我们在其内部是不能修改外部局部变量的值,如果非要修改就要在变量前面加__block,于是我们就一直这么做了,但为什么加上修饰就可以了呢,这个问题今天我决定好好研究一下。

首先看一下Block的分类

NSGlobalBlock:全局block,只要内部没使用外部变量就是全局block。

NSStackBlock和NSMallocBlock:当内部使用外部变量就会变成栈block,当将block从栈去拷贝到堆区就是变成堆block。

首先看一段代码

int a = 0;

1     NSLog(@"a --%p",&a);

void (^test)(void) = ^{

2     NSLog(@"a --%p",&a);

};

3     NSLog(@"a --%p",&a);

test();

代码的输出顺讯为1-3-2,输出结果

2017-10-16 09:49:23.171 fsafdafasf[3674:471719] a --0x7fff4ff9aa2c

2017-10-16 09:49:23.171 fsafdafasf[3674:471719] a --0x7fff4ff9aa2c

2017-10-16 09:49:23.172 fsafdafasf[3674:471719] a --0x600000051cc0

从输出结果可以看出block内和block外是两个作用域,内部的指针a和外部的指针a虽然名字一样但他们的内存地址已经不同了,这也就是我们可以内部修改局部变量的原因。在block内部会将局部变量的指正复制一份,这样内部和外部就不是一个指针了,就算你重新给内部指针赋值,也无法改变外部指针的指向,他们只是名字相同。

接下来再看一段代码

__block int a = 0;

NSLog(@"a --%p",&a);

void (^test)(void) = ^{

NSLog(@"a --%p",&a);

};

NSLog(@"a --%p",&a);

test();

输出结果  1-3-2

2017-10-16 09:58:15.551 fsafdafasf[3711:476037] a --0x7fff5de71a28

2017-10-16 09:58:15.552 fsafdafasf[3711:476037] a --0x6000000283d8

2017-10-16 09:58:15.552 fsafdafasf[3711:476037] a --0x6000000283d8


结论

没有通过__block修饰则是将值传进去,而通过__block修饰之后是将变量的内存地址传进去,这样就可以修改变量的值。

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

相关阅读更多精彩内容

  • iOS面试小贴士 ———————————————回答好下面的足够了------------------------...
    不言不爱阅读 6,502评论 0 7
  • ———————————————回答好下面的足够了---------------------------------...
    恒爱DE问候阅读 5,743评论 0 4
  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 6,177评论 0 12
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 8,808评论 0 6
  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 9,181评论 0 23

友情链接更多精彩内容