__block变量的成员变量__forwarding存在的意义
</br>
__block变量结构体中的__forwarding成员变量是个指向自身的指针,为什么需要这样一个“多此一举”的变量呢?
Block从栈复制到堆上时,__forwarding发生的变化:
Block复制后,栈上__block变量的__forwarding指针被修改,指向了堆上的__block变量。
通过__forwarding指针,我们可以实现,无论是在Block语法中、Block语法外,还是__block变量配置在栈上或堆上,都可以顺利访问同一个__block变量
下面是分别在Block语法中和Block语法外访问__block变量的例子�,这能反映__forwarding成员变量存在的意义:
__block int val = 0;
void (^blk)(void) = [^{++val; } copy]; //语句1
++val; //语句2
blk(); //语句3
NSLog("%d", val);
代码分析:
语句1
的copy方法把Block从栈复制到堆。现在栈和堆上都有这个Block。语句2
和语句3
都是访问__block变量,但它们有所区别:语句2
�在Block语法外访问__block变量,并且访问的是栈上的__block变量;语句3
�在Block语法中访问__block变量,并且也是访问栈上的__block变量。所以语句2
和语句3
都等价于
++(val.__forwarding->val);
虽然它们访问的都是栈上的__block变量,但因为Block执行复制之后,__forwarding会修改为指向堆上的__block变量,所以本质上访问的是堆上的__block变量。
�假如没有__forwarding成员变量,我们执行上例的代码时,++val;
和blk();
两条语句访问的都是栈上__block变量。这样你看出问题了吗?栈上和堆上的__block变量的值不一致了:一旦栈上的__block变量随着Block变量作用域结束被废弃而被废弃,稍后访问堆上的__block变量时,访问到的是个错误(不是预期想要的)的值。