我在将NSCoder支持写入课程时遇到了一点意外。我有一个类A,它包含rgb结构类型的公开'color'属性。我有另一个B级,它扩展了A。
要对B类的encodeWithCoder方法中的color属性进行编码,我首先将它包装到NSValue中,如下所示:
[NSValue value:&(self.color)]
但是,使用此代码会导致以下编译错误:
Lvalue required as unary '&' operand.
通过在使用NSValue进行换行之前简单地将self.color复制到方法范围值,这很容易解决,但是我想了解何时会发生这种情况以及为什么会发生这种情况的规则。由于不需要存在该属性名称的真实类字段,因此任何@synthesize属性都会发生这种情况,因此没有保证对象指向?
答案 0 :(得分:4)
您无法获取函数(或方法)返回的内容的地址。您需要直接获取color
ivar的地址(即&color
)。在您的情况下,我建议您使用自己提出的方法(id tempCol = self.color; [NSValue value:&tempCol];
)。
请注意,使用点表示法时会调用方法。
self.color
// is equal to
[self color]
&([self color])
也是不可能的,因为&
在编译时解析,而不是在运行时解析。 [self color]
和self.color
的返回值(相等)在编译时尚不可知(即使使用@synthesize
,因为您可以在Objective-C中更改方法的实现在运行时(例如使用方法调配或使用类别))。
您似乎并不完全理解@synthesize
的作用,所以我会解释一下。 :)
基本上@synthesize
的作用是:编译器根据给定的属性名称生成方法及其实现。
例如,此属性:
@property(nonatomic, retain) NSColor *color;
与此合成一起:
@synthesize color;
将在@implementation
:
- (NSColor *)color {
return color;
}
- (void)setColor:(NSColor *)newColor {
if (color == newColor) { return; }
NSColor *theOldColor = color;
color = [newColor retain];
[theOldColor release];
}
当您想使用自己的setter或getter时,只需使用相同的方法名称在@implementation
中定义它们即可。例如,如果没有设置,您可以返回默认颜色:
- (NSColor *)color {
if (color) { return color; }
return [NSColor whiteColor];
}
现在编译器将生成setter,但不会生成getter:它将使用您提供的getter,您仍然可以将其与self.color
一起使用。
您可能需要查看Apple's guide on properties。
答案 1 :(得分:3)
规则很简单。编译器转换属性访问:
self.color
进入方法调用*
[self color]
表示&(self.color)
变为&([self color])
。然后编译器抱怨,因为你不能接受方法调用的地址。
*如果您要分配属性,则分配将转换为对setter的调用:self.color = aColor;
- > [self setColor:aColor];
。