13

Objective-C では、インスタンス変数を宣言すると、コンパイル時に割り当て時にプロトコルに準拠しているかどうかを次のように確認できます。

id <MyProtocol> variable;

変数に割り当てられたオブジェクトがコンパイル時に 2 つの別々のプロトコルに準拠しているかどうかを確認することはできますか? 次のように:

id <MyProtocol, MyOtherProtocol> variable;

conformsToProtocol:and などを使用して実行時チェックを実行できることはわかっていますrespondsToSelector(これは、安全性を高めるために実際にオブジェクトを使用する前に実行します)。また、チェックを実行する独自のセッター メソッドを作成することもできますが、コンパイル時に知りたいです。

4

3 に答える 3

55

はい、その構文は正しいです。

オブジェクトがプロトコルに準拠しているかどうかを確認する正しい方法は、次のとおりです。

if ([myObj conformsToProtocol:@protocol(MyProtocol)]) {
  //conformance!
}

これは、インスタンス メソッドとクラス メソッドの両方として機能することに注意してください。

何らかの奇妙な理由で を使用できない場合はconformsToProtocol:、ランタイム レベルにドロップダウンできます。

#import <objc/runtime.h>

Protocol * p = objc_getProtocol("MyProtocol");
if (class_conformsToProtocol([myObj class], p)) {
  //conformance!
}
于 2011-01-10T16:58:39.363 に答える
13

独自のコードを使用するのが最善だと思います:

id <MyProtocol, MyOtherProtocol> variable;

メソッドを呼び出す前に、変数が呼び出したいものに応答するかどうかを確認します。

if ([variable respondsToSelector:@selector(aMethod:)]) {
    [variable aMethod:nil];
}

Objective-C は動的言語であるため、変数プロトコルを宣言するだけでは、それがプロトコルに準拠していることを保証できません。ほとんどの場合、ビルド時に警告が生成されます。

于 2011-01-10T14:06:17.463 に答える
3

id(修飾されていない) 型のオブジェクトは、コンパイラの観点からは常に有効なオブジェクトであるため、コンパイル時に常にプロトコルの適合性を確認できるとは限りません。例えば、

id<P1> p1;
id<P2> p2;
id p0;

// compiler warning: assigning to 'id<P1>' from incompatible type 'id<P2>'
p1 = p2;

// no compiler warning
p0 = p2;
p1 = p0;

そうは言っても、オブジェクトが両方のプロトコルに準拠していない場合は、コンパイル時にそれ<P1, P2>がわかれば警告が表示されます。

id<P1> p1;
id<P2> p2;
id<P1, P2> p12;
id<P1, P2> q12;
id p0;

p12 = p1; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P1>'
p12 = p2; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P2>'
p12 = q12; // no compiler warning

// no compiler warning
p0 = p1;
p12 = p0;
于 2011-01-10T14:02:01.583 に答える