vicki753's iOS 基础-Objective-C -- Block

__block int val = 0;
NSLog(@"val plus0 %p", &val);//0x0
void (^blk)(void) ;
NSLog(@"blk plus0 %p", &blk);
blk=[^{
++val;
NSLog(@"val plus1 %p", &val);//0x2
} copy];
NSLog(@"blk plus1 %p", &blk);
NSLog(@"val value0 = %d", val);//0
++val;
NSLog(@"val plus3 %p", &val);//0x2
NSLog(@"val value2 = %d", val);//1
blk();
NSLog(@"val plus4 %p", &val);//0x2
NSLog(@"val vlaue3 = %d", val);//2
blk();
NSLog(@"val plus5 %p", &val);//0x2
NSLog(@"val vlaue4 = %d", val);//2
int otherValOne = ++val; //先加在赋值
int otherValTwo = val;
int otherValThree = val++;//赋值了再加
NSLog(@"otherOne %d", otherValOne);
NSLog(@"otherTwo %d", otherValTwo);
NSLog(@"otherThree %d",otherValThree);

运行的结果:

  val plus0  0x7fff55b28c40
  blk0 0x7fff55300c10
  blk1 0x7fff55300c10
  val value0 = 0
  val plus3  0x604000432678
  val value2 = 1
  val plus1  0x604000432678
  val plus4 0x604000432678
  val vlaue3 = 2
  val plus1  0x604000432678
  val plus5 0x604000432678
  val vlaue4 = 3
  otherOne 4
  otherTwo  4
  otherThree 4

1、这里的val地址为什么从0x7fff55b28c40 ,变为0x604000038b98 呢?因为block在定义的时候是在stack的,
^{
++val;
NSLog(@"val plus1 %p", &val);//0x2
};
这是一个Block量
后面用的 copy,__block 变量会在block(执行还是定义?)时候copy进堆内存,之前它是在栈内存的,也就是从栈上复制到堆上,这时候的val变量(因为是局部变量,所以也在栈中)也会被复制一份在堆中,这时候的地址就不一样的,(其实我明白这应该是block量里面的变量才应该这样的,也就是 block在执行的时候里面的val的地址才应该不同,到后来所有的调用都为block的变量val了,(这一点我不明白),然后block复制在堆上了以后,里面有一个__isa指针和一个__forwarding指针,这个__forwarding 指针是指向自己本身的,所以,在复制过来的时候__forwarding指向了堆上的地址了,同时堆上的__forwarding指针也指向的自己。所以这样都是指向的同一个block(对象)也不会有指向错误。这也就是为什么,里面的val变量都是在同一个地址了,此时变量val的生命周期也就是这个blk的生命周期了,当blk结束,__block也就是结束了,这也许就是我刚刚不懂val后面的地址都是同一个地址的原因。

你可能感兴趣的:(vicki753's iOS 基础-Objective-C -- Block)