__block关键字

前提:Objective-C规定,在block中不能修改外部变量的值,若想修改则需在变量前边加__block关键字修饰
理解:

- (void)_testBlock{
   int a = 0;
  NSLog(@"block before:%p",&a);
  void (^func)(void) = ^{
      NSLog(@"block in:%p",&a);
  };
  NSLog(@"block after:%p",&a);
  func();
}

block中不能修改外部变量的值?
block中外部变量的值是被拷贝过去的,相当于值引用,并非变量原地址;
由上方代码的输出结果可见:

2021-08-20 14:05:46.036124+0800 block[37717:3248973] block before:0x7ffee33f913c
2021-08-20 14:05:46.036269+0800 block[37717:3248973] block after:0x7ffee33f913c
2021-08-20 14:06:13.870278+0800 block[37717:3248973] block in:0x600001d272f0

block before和block after的地址一致,和block内的地址不同,说明变量的地址没变,相当于值引用

加__block关键字之后,可以修改了?
前边加入__block关键字修饰之后,变量地址会被拷贝到堆区

2021-08-20 14:10:38.858026+0800 block[37764:3253396] block before:0x7ffee4427138
2021-08-20 14:10:38.858209+0800 block[37764:3253396] block after:0x6000007c2ef8
2021-08-20 14:11:05.778524+0800 block[37764:3253396] block in:0x6000007c2ef8

block in和block after的地址是一致的,说明变量的地址变化,相当于地址引用
我们可以更进一步,利用clang 生成runtime编译后的源文件,加深理解

  1. 加深理解

方式:利用clang -rewrite-objc 生成编译后的代码,用源码解读

你可能感兴趣的:(__block关键字)