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:
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];
.