2009-04-12 43 views
9

我有一個簡單的協議與一個屬性:鍵 - 值觀察在協議對象:編譯器警告上的addObserver:

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

我添加一個鍵值觀察者別處聽更改「停止」屬性:

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方法帶入我的協議,而不是將聲明覆制到協議本身,這似乎是一個黑客。

我知道這是一個微不足道的問題,因爲它只是一個編譯器警告,但我很想知道是否有「正確」的方法來解決這個問題。

+2

見Abizern的回答的重要信息,但您的具體問題,用NSObject替換'id ' * source = ... – 2009-04-12 02:13:18

回答

12

真正的煩惱是對的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)。這就是爲什麼你會收到警告。

傑森可可告訴你他對你的問題的評論,解決的辦法就是改變使用NSObject類加上您的協議聲明:

NSObject <StopsSource> *source = …; 
0

我想你可能會對協議的功能感到困惑;它只是定義了一組可以由另一個類實現的操作。

協議中唯一的東西就是屬性。

此外,爲什麼你聲明這符合NSObject協議?你不需要這樣做,因爲如果你有一個採用你的協議的類,它將繼承自NSObject,並且符合。即

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

協議可以包括除方法以外的屬性。請參閱以下網址中的MyXMLSupport協議示例: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF148 – 2009-04-12 02:27:07