Objective-C を使用して実行時にセレクターを動的に作成するにはどうすればよいですか?
-
02-07-2019 - |
質問
の作成方法を知っています SEL
コンパイル時に使用して @selector(MyMethodName:)
しかし、私がやりたいのは、セレクターを動的に作成することです NSString
. 。これも可能でしょうか?
私は何ができますか:
SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];
私がしたいこと:(疑似コード、これは明らかに機能しません)
SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];
Apple APIドキュメントを検索していますが、コンパイル時間に依存しない方法が見つかりませんでした @selector(myTarget:)
構文。
解決
私は Objective-C プログラマではなく、単なる同調者ですが、おそらく NSSelectorFromString 必要なものです。で明確に言及されています ランタイムリファレンス これを使用して文字列をセレクターに変換できることを示します。
他のヒント
XCode のドキュメントによると、疑似コードは基本的に正しく動作します。
コンパイル時に @selector() ディレクティブを使用して SEL 変数に値を割り当てるのが最も効率的です。ただし、場合によっては、プログラムの実行時に文字列をセレクターに変換する必要があります。これは NSSelectorFromString 関数を使用して実行できます。
setWidthHeight = NSSelectorFromString(aBuffer);
編集:残念、遅すぎます。:P
そう言わざるを得ません それはもう少し複雑です 前の回答者の回答が示唆しているよりも...本当に本当にそうしたいなら セレクターを作成する...「横たわっている」ものを「電話する」だけではありません...
「新しい」メソッドによって呼び出される関数ポインターを作成する必要があります。したがって、次のようなメソッドの場合 [self theMethod:(id)methodArg];
, 、あなたはこう書きます...
void (^impBlock)(id,id) = ^(id _self, id methodArg) {
[_self doSomethingWith:methodArg];
};
そして、それを生成する必要があります IMP
動的にブロックし、今回は「self」を渡します。 SEL
, 、および引数...
void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock);
そして、それを吸盤全体の正確なメソッド署名とともにクラスに追加します(この場合) "v@:@"
, 、void 戻り値、オブジェクト呼び出し元、オブジェクト引数)
class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");
この種の良い例をいくつか見ることができます ランタイムの悪ふざけ, 、私のリポジトリの 1 つで、ここにあります。
これについてはずっと前に答えられているのは承知していますが、それでも共有したいと思います。これは次を使用して実行できます sel_registerName
あまりにも。
質問内のサンプルコードは次のように書き換えることができます。
SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];