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

发布于 2024-07-17 08:38:07 字数 870 浏览 5 评论 0原文

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

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

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

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 方法引入我的协议中,而不是将声明复制到协议本身中,这看起来像是一个黑客。

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

I have a simple protocol with a property:

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

I'm adding a key-value observer elsewhere to listen to changes to the "stops" property:

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

Code works as expected in that I get observeValueForKeyPath events when the "stops" property is changed. The real annoyance is a compiler warning on the addObserver call:

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

The 'addObserver' method is defined in a category to NSObject:

@interface NSObject(NSKeyValueObserverRegistration)

Is there any way to get XCode to drop this warning? It's my understanding that protocols can't adopt categories, so I'm not sure how to bring the NSKeyValueObserverRegistration methods into my protocol, short of copying the declarations into the protocol itself, which seems like a hack.

I know this is kind of a trivial problem, in that it's just a compiler warning, but I'm interested to know if there is a "right" way to address this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

万水千山粽是情ミ 2024-07-24 08:38:07

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

<块引用>

警告:在协议中找不到“-addObserver:forKeyPath:options:context:” 
  

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

@interface NSObject(NSKeyValueObserverRegistration) 
  

有什么方法可以让 XCode 放弃这个警告吗?

Xcode(小写 c)只是向您显示警告; 首先是 GCC(编译器)向您发出警告。

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

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

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

NSObject <StopsSource> *source = …;

The real annoyance is a compiler warning on the addObserver call:

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

The 'addObserver' method is defined in a category to NSObject:

@interface NSObject(NSKeyValueObserverRegistration)

Is there any way to get XCode to drop this warning?

Xcode (lowercase c) is just showing you the warning; it's GCC, the compiler, that's giving you the warning in the first place.

You're confusing the class NSObject with the protocol NSObject. The NSObject class conforms to the NSObject protocol, among others, but protocols have no relation of their own to classes. Your StopsSource protocol, being a protocol, inherits from the NSObject protocol, not the NSObject class.

Your declaration only covers those two protocols, and not any specific class, so it doesn't include anything outside those protocols that the NSObject class may implement (such as KVO). That's why you get the warning.

As Jason Coco told you in his comment on your question, the solution is to change the declaration to use the NSObject class plus your protocol:

NSObject <StopsSource> *source = …;
小ぇ时光︴ 2024-07-24 08:38:07

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

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

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

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

I think you may be getting confused about what a protocol does; it is just defines a set of operations that can be implemented by another class.

The only thing in your protocol is a property.

Also, why are you declaring this to conform to the NSObject protocol? You don't need to do this because if you have a class that adopts your protocol, it will inherit from NSObject, and so will conform to . i.e

@interface YourClass : NSObject <StopSource> {
    // etc
@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文