objective-cpropertiesivar

What data type do ivars for primitive properties have?


I am asking because the I was dabbling into some complicated block code and I did not expect the following code to work properly.

Say we have a BOOL property, as so:

@property (nonatomic, assign) BOOL isCancelled;

It's auto synthesised, no custom getter, no setter, no explicit ivar.

Then, there's this code... which works perfectly

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

However, I would have expected it work for the block() call, but not for the if, where I thought it would capture the value of _isCancelled and keep it const, not have it mutate throughout execution. Still, at runtime, the value of _isCancelled is always consistent inside/outside the block, as if it were actually BOOL *

Can anyone explain what's going on?


Solution

  • When declaring a property BOOL cancelled the autosynthesized ivar is BOOL _isCancelled. This is a primitive variable, not a pointer.

    However, when a block is capturing ivars, it is actually capturing self, not the ivar itself. Reading ivar _isCancelled actually means reading self->_isCancelled.

    Therefore, ivars are not captured by value unless you save them into a local variable first (e.g. BOOL isCancelled = _isCancelled).

    See Block automatic retaining, does it affect even to ivars in self? for more information.