原始属性的ivars有哪些数据类型?

时间:2017-01-25 22:18:13

标签: objective-c properties ivar

我在问,因为我正在涉及一些复杂的块代码,我不希望以下代码正常工作。

假设我们有一个BOOL属性,如下:

@property (nonatomic, assign) BOOL isCancelled;

它是自动合成的,没有自定义的吸气剂,没有固定器,也没有明确的静脉注射器。

然后,这段代码......完美无缺

dispatch_async(queue, ^{
    id result = block(&_isCancelled);
    if (!_isCancelled) { ... }
}

但是,我本来期望它适用于block()调用,但不适用于if,我认为它会捕获_isCancelled的值并保持const,而不是在整个执行过程中进行变异。仍然,在运行时,_isCancelled的值在块内/外总是一致的,就好像它实际上是BOOL *

有谁可以解释发生了什么?

2 个答案:

答案 0 :(得分:0)

TL; DR:与属性相同的类型。

所有对象指针和基元类型都是标量值 - 即奇异值。它们都需要存储在内存中的地址中,因此它们都有自己的内存地址。

通过& _isCancelled,您传递BOOL变量的地址,因此block()已被“放进秘密” - 即BOOL的位置 - 所以它可以更新它。然后,您将检查_isConnected的结果实际值。这适用于原始类型(标量)和对象指针(也是标量)。

它的财产是否无关紧要。

答案 1 :(得分:0)

声明属性BOOL cancelled时,自动合成的 ivar BOOL _isCancelled。这是一个原始变量,而不是指针。

然而,当一个块正在捕获ivars时,它实际上是捕获self,而不是ivar本身。阅读ivar _isCancelled实际上意味着阅读self->_isCancelled

因此,除非您先将它们保存到局部变量(例如BOOL isCancelled = _isCancelled),否则不会按值捕获ivars。

有关详细信息,请参阅Block automatic retaining, does it affect even to ivars in self?