协议对象上的键值观察:addObserver上的编译器警告:

时间:2009-04-12 01:39:51

标签: objective-c cocoa key-value-observing

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

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

我正在其他地方添加一个键值观察器来监听“停止”属性的更改:

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

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

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

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

@interface NSObject(NSKeyValueObserverRegistration)

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

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

2 个答案:

答案 0 :(得分:13)

  

真正的烦恼是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 = …;

答案 1 :(得分:0)

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

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

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

@interface YourClass : NSObject <StopSource> {
    // etc
@end