メソッドが存在するかどうかを確認します


110

Objective-Cにメソッドが存在するかどうかをテストする方法はありますか?

呼び出す前にオブジェクトにメソッドがあるかどうかを確認するためにガードを追加しようとしています。


Objective-Cクラスは、(を介して- forwardInvocation:)宣言していないセレクターに応答できるため、これが正しいアプローチであるかどうかという問題もあります。
ドナルフェロー

回答:


189
if ([obj respondsToSelector:@selector(methodName:withEtc:)]) {
   [obj methodName:123 withEtc:456];
}

72

静的なメッセージinstanceRespondToSelector:(SEL)selectorもあります。次の ように呼び出します。

[MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]

またはこのように:

[[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]

これは、これに応じて(つまり、インスタンス自体を取得する前に)あるコンストラクターまたは別のコンストラクターを呼び出す場合に役立ちます。


1
instancesRespondToSelectorとrespondsToSelectorの違いは何ですか?
CReaTuS 2012

1
主な違いは、1つはインスタンスメッセージ(決定されたインスタンスメッセージが存在するかどうかをテストするため)であり、もう1つはクラスメッセージ(決定されたクラスメッセージが存在するかどうかをテストするため)です。
RicardPérezdel Campo

1
+1 [MyClass instancesRespondToSelector]の場合。私はinit作成メソッド内でそれを必要としました:自己がまだ作成されておらず、respondsToSelectorが常にNOを返すため、サブクラス化が他の1つ(非推奨のもの)ではなく1つのスーパーinitメソッドを呼び出す必要がある場合。
LightMan

12

を使用しrespondsToSelector:ます。ドキュメントから:

respondsToSelector:

指定したメッセージに応答できるメソッドをレシーバーが実装するか継承するかを示すブール値を返します。

- (BOOL)respondsToSelector:(SEL)aSelector

パラメータ
aSelector-メッセージを識別するセレクタ。


YESレシーバがaSelectorに応答できるメソッドを実装または継承する場合の戻り値、そうでない場合NO


10

あなたはrespondsToSelectorを探しています: -

if ([foo respondsToSelector: @selector(bar)] {
  [foo bar];
}

ドナルが言う上記のfooができることを示しています間違いなくバーセレクタを受けて処理します。ただし、fooがbarメッセージを受信する基になるオブジェクトにbarを転送するプロキシである場合、メッセージはbarに応答するオブジェクトに転送されますが、respondsToSelector:はNOを通知します。


1

respondsToSelectorを使用したセレクターのチェックは、通常、デリゲートメソッド専用です。デリゲートメソッドにforwardInvocationまたはプロキシを使用しないでください。他の状況でrespondsToSelectorを使用する必要がある場合は、プログラムを設計するためのより適切な方法がないことを確認したい場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.