【问题标题】:Accessing Property Values of a Protocol?访问协议的属性值?
【发布时间】:2010-12-02 16:15:39
【问题描述】:

大家好,我有一个协议,它定义了许多 ObjC-2.0 属性,如下所示:

@protocol Repeatable <NSCoding>
@required
@property (nonatomic, retain) Date *startDate;
@property (nonatomic, retain) Date *endDate;
@end

我有另一个实现协议的类:

@interface AbstractRepeatable : NSObject <Repeatable>

最后,在 AbstractRepeatable 中,我正在实现协议定义的方法:

- (BOOL)isEqualToRepeatable:(Repeatable *)r {
    if (r.startDate != startDate) // Compiler error here
        return NO;
    return YES;
}

出于示例的原因,已排除了一些零碎的内容,但是在编译时,我在上面提到的行中收到了熟悉的“对成员 'startDate' 的请求,而不是结构或联合”。 AbstractRepeatable 显然包含Repeatable 标头,否则协议将不可见,所以我不知道我缺少哪个部分。

【问题讨论】:

  • 这个答案可能会为您解决一些问题:stackoverflow.com/questions/844678/…
  • 我正在合成 AbstractRepeatable 中的属性,我无法弄清楚为什么无法识别该道具。

标签: iphone objective-c xcode macos properties


【解决方案1】:

在您的isEqualToRepeatable: 方法中,您将Repeatable 视为一个类,而不是一个协议。尝试使用以下内容。之后一切都应该正常工作。我测试了它。 (手指交叉,我不会看起来很愚蠢。)

- (BOOL)isEqualToRepeatable:(id<Repeatable>)r {
    if (r.startDate != startDate) // Compiler error here
        return NO;
    return YES;
}

【讨论】:

  • 我很惊讶完全解决了这个问题。在协议中使用@property() 的现有编译器存在严重错误。
【解决方案2】:

这应该可以正常工作,并且符合您的预期。但这不是因为编译器坏了。

对此感到抱歉。

作为一种解决方法,您需要在协议中声明方法:

@protocol Repeatable <NSCoding>
@required
@property (nonatomic, retain) Date *startDate;
- (Date *) startDate;
- (void) setStartDate: (Date *) aDate;

@property (nonatomic, retain) Date *endDate;
- (Date *) endDate;
- (void) setEndDate: (Date *) aDate;
@end

如果你愿意,可以跳过@property。一旦编译器被修复,上面仍然不会产生任何警告。

(是的,你仍然可以@synthesize 方法。我相信@synthesize 在这种情况下会起作用。如果它不起作用——它可能不会——那么你需要重新声明类中的属性-- 可能在类扩展中 -- 直到编译器被修复。如果证明是第二个问题,请通过http://bugreport.apple.com/提交错误)

【讨论】:

  • 我相信编译器正在合成 getter/setter。请参阅所选答案以获得良好的解释。
  • 编译器正在合成 getter/setter。那不是问题。问题是编译器在类声明中没有看到 @property() 表明正确地需要方法。在某些情况下,它会导致错误的代码生成。
【解决方案3】:

@property ... startDate 只声明了两个方法-startDate-setStartDate:

您必须实际实施它们。在协议中,这不能通过实例变量来完成。

【讨论】:

  • 在协议中定义属性只是确保子类(或实现者,更具体地说)合成属性,并且您可以将任何可重复传递给方法,并具有作用于这些属性的代码,假设它们存在于实际对象中,这是该协议的实现。
  • 我应该澄清一下 - 在协议中定义属性不会综合变量。协议的任何实现必须综合(或提供动态访问器方法)以确保“维护”属性。
  • 这是一个很好的观点。您是否尝试将 (r.startDate != startDate) 替换为 (r.startDate != [self startDate]) ?
  • 编译器错误出现在 r.startDate 'getter' 上,而不是 startDate 实例变量上。上面选择的答案。 :)
  • 在 XCode 4.4 中,我们得到了以下更改:“Objective-C @properties 在未显式实现时默认合成。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2016-12-17
  • 2018-07-15
  • 1970-01-01
  • 2014-02-26
相关资源
最近更新 更多