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?
The rule is simple enough. The compiler turns a property access:
into a method call*
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];.