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

Bri*_*ris 10 cocoa objective-c key-value-observing

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

@protocol StopsSource <NSObject>
@property (retain,readonly) NSArray * stops;
@end
Run Code Online (Sandbox Code Playgroud)

我在别处添加一个键值观察器来监听"stops"属性的更改:

id<StopsSource> source = ...
[source addObserver:self
         forKeyPath:@"stops"
            options:NSKeyValueObservingOptionNew
            context:nil];
Run Code Online (Sandbox Code Playgroud)

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

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s)
Run Code Online (Sandbox Code Playgroud)

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

@interface NSObject(NSKeyValueObserverRegistration)
Run Code Online (Sandbox Code Playgroud)

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

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

Pet*_*sey 13

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

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s)
Run Code Online (Sandbox Code Playgroud)

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

@interface NSObject(NSKeyValueObserverRegistration)
Run Code Online (Sandbox Code Playgroud)

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

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

您将NSObject 协议 NSObject 混淆.NSObject类符合NSObject协议等,但协议与类没有关系.作为协议的StopsSource协议继承自NSObject协议,而不是NSObject类.

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

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

NSObject <StopsSource> *source = …;
Run Code Online (Sandbox Code Playgroud)