美文网首页
Objective-C的Block实质与实现探究 part-9

Objective-C的Block实质与实现探究 part-9

作者: KardelShaw | 来源:发表于2017-01-04 01:42 被阅读0次

__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变量时,访问到的是个错误(不是预期想要的)的值。

相关文章

网友评论

      本文标题:Objective-C的Block实质与实现探究 part-9

      本文链接:https://www.haomeiwen.com/subject/leqovttx.html