11

我有一个带有属性的简单协议:

@protocol StopsSource <NSObject>
@property (retain,readonly) NSArray * stops;
@end

我在其他地方添加了一个键值观察器来监听“stops”属性的变化:

id<StopsSource> source = ...
[source addObserver:self
         forKeyPath:@"stops"
            options:NSKeyValueObservingOptionNew
            context:nil];

代码按预期工作,因为当“停止”属性更改时,我得到了 observeValueForKeyPath 事件。真正的烦恼是 addObserver 调用上的编译器警告:

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s)

'addObserver' 方法在 NSObject 的类别中定义:

@interface NSObject(NSKeyValueObserverRegistration)

有没有办法让 XCode 放弃这个警告?我的理解是协议不能采用类别,所以我不确定如何将 NSKeyValueObserverRegistration 方法引入我的协议中,而不是将声明复制到协议本身中,这似乎是一种 hack。

我知道这是一个微不足道的问题,因为它只是一个编译器警告,但我很想知道是否有一种“正确”的方法来解决这个问题。

4

2 回答 2

14

真正的烦恼是 addObserver 调用上的编译器警告:

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s)

'addObserver' 方法在 NSObject 的类别中定义:

@interface NSObject(NSKeyValueObserverRegistration)

有没有办法让 XCode 放弃这个警告?

Xcode(小写 c)只是向您显示警告;它是编译器 GCC,它首先给你警告。

您将NSObject协议NSObject 混淆了。NSObject 类遵守 NSObject 协议等,但协议与类没有关系。您的 StopsSource 协议,作为一个协议,继承自 NSObject 协议,而不是 NSObject 类。

您的声明仅涵盖这两个协议,而不是任何特定的类,因此它不包括 NSObject 类可能实现的那些协议之外的任何内容(例如 KVO)。这就是你收到警告的原因。

正如 Jason Coco 在他对您的问题的评论中告诉您的那样,解决方案是更改声明以使用 NSObject 类和您的协议:

NSObject <StopsSource> *source = …;
于 2009-04-12T03:13:53.800 回答
0

我认为您可能对协议的作用感到困惑;它只是定义了一组可以由另一个类实现的操作。

你的协议中唯一的东西是一个属性。

另外,你为什么要声明它符合 NSObject 协议?您不需要这样做,因为如果您有一个采用您的协议的类,它将继承自 NSObject,因此将符合 . IE

@interface YourClass : NSObject <StopSource> {
    // etc
@end
于 2009-04-12T01:59:40.157 回答