Search code examples
objective-cpointerslvaluenscoder

Objective-C struct property pointer cannot be made via self.prop?


I've just encountered a little surprise whilst writing NSCoder support into a class. I have a class A which contains an exposed 'color' property of an rgb struct type. I have another class B which extends A.

To encode the color property within class B's encodeWithCoder method I've first wrapped it into an NSValue like so:

[NSValue value:&(self.color)]

However using this code causes the following compilation error:

Lvalue required as unary '&' operand.

It's easy enough to get around by simply copying self.color to a method-scope value before wrapping with NSValue, but I'd like to understand the rule for when this will happen, and why it occurs. Will this happen with any @synthesize property due to there being no need for a true class field of that property name to exist, hence no guaranteed object to point to?


Solution

  • The rule is simple enough. The compiler turns a property access:

    self.color
    

    into a method call*

    [self color]
    

    which means that &(self.color) turns into &([self color]). Then the compiler complains, because you can't take the address of a method call.


    *If you were assigning to the property, the assignment would be transformed into a call to the setter: self.color = aColor; -> [self setColor:aColor];.