3

在将 NSCoder 支持写入一个类时,我刚刚遇到了一个小惊喜。我有一个 A 类,其中包含 rgb 结构类型的公开“颜色”属性。我有另一个扩展 A 的 B 类。

为了在 B 类的 encodeWithCoder 方法中对颜色属性进行编码,我首先将它包装到一个 NSValue 中,如下所示:

[NSValue value:&(self.color)]

但是,使用此代码会导致以下编译错误:

Lvalue required as unary '&' operand.

在使用 NSValue 包装之前,只需将 self.color 复制到方法范围值就很容易解决,但我想了解何时发生这种情况的规则,以及发生这种情况的原因。由于不需要该属性名称的真实类字段存在,因此任何@synthesize 属性都会发生这种情况,因此没有保证指向的对象?

4

2 回答 2

4

您无法获取函数(或方法)返回的内容的地址。您需要直接获取colorivar 的地址(即&color)。不过,在您的情况下,我建议使用您自己提出的方法(id tempCol = self.color; [NSValue value:&tempCol];)。


请注意,使用点表示法时会调用方法。

self.color
// is equal to
[self color]

&([self color])也是不可能的,因为&在编译时解决,而不是在运行时解决。[self color]and的返回值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 的属性指南

于 2011-08-18T18:47:55.077 回答
3

规则很简单。编译器转换属性访问:

self.color

进入方法调用*

[self color]

这意味着&(self.color)变成&([self color]). 然后编译器抱怨,因为你不能获取方法调用的地址。


*如果您分配给属性,则分配将转换为对 setter 的调用:self.color = aColor;-> [self setColor:aColor];

于 2011-08-18T18:49:34.087 回答