【问题标题】:Objective-C struct property pointer cannot be made via self.prop?Objective-C struct 属性指针不能通过 self.prop 生成?
【发布时间】:2011-08-18 18:45:09
【问题描述】:

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

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

[NSValue value:&(self.color)]

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

Lvalue required as unary '&' operand.

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

【问题讨论】:

    标签: objective-c pointers lvalue nscoder


    【解决方案1】:

    您无法获取函数(或方法)返回的内容的地址。您需要直接获取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

    【讨论】:

    • 我想这对我来说似乎并不明显,因为我最近没有使用自动设置器/获取器的语言工作!感谢 WTP。
    【解决方案2】:

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

    self.color
    

    进入方法调用*

    [self color]
    

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


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

    【讨论】:

    • 简洁而恰到好处的细节,谢谢乔希!给你分数,因为 WTP 清楚地调整了他的答案,以重复你在发布后所说的话。
    • 在我看来,WTP 并没有恶意抄袭我,但我很高兴你发现我的回答很有用。
    • 从最纯粹的意义上说,这并不是恶意的,我很感谢他最初的帮助,但是当这里的人们调整他们的答案以模仿随之而来的更好答案的内容时,这让我很恼火。您的答案正是我们所需要的,仅此而已。
    猜你喜欢
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多