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 メソッドを組み込む方法がわかりません。これはハックのようです。

これは単なるコンパイラの警告であるという点で、些細な問題であることはわかっていますが、これに対処する「正しい」方法があるかどうかを知りたいと思っています。

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 プロトコルから継承します。

あなたの宣言は、特定のクラスではなく、これら 2 つのプロトコルのみを対象としているため、NSObject クラスが実装する可能性のあるプロトコル以外 (KVO など) は含まれていません。そのため、警告が表示されます。

Jason Coco があなたの質問に対するコメントで言ったように、解決策は宣言を変更して NSObject クラスとプロトコルを使用することです。

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

プロトコルの機能について混乱しているかもしれません。別のクラスで実装できる一連の操作を定義するだけです。

プロトコルの唯一のものはプロパティです。

また、なぜこれが NSObject プロトコルに準拠していると宣言しているのですか? プロトコルを採用するクラスがある場合、それは NSObject から継承されるため、これを行う必要はありません。すなわち

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