Objective-Cで実行時にセレクターを動的に作成するにはどうすればよいですか?


93

SEL使用してコンパイル時に作成する方法を知っています@selector(MyMethodName:)が、私がやりたいことは、から動的にセレクターを作成することですNSString。これは可能ですか?

私は何ができますか:

SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];

私がやりたいこと:(疑似コード、これは明らかに動作しません)

SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];

私はApple APIのドキュメントを検索してきましたが、コンパイル時の@selector(myTarget:)構文に依存しない方法を見つけていません。

回答:


180

私はObjective-Cプログラマではなく、単なる同情者ですが、おそらくNSSelectorFromStringが必要です。文字列をセレクターに変換するために使用できることは、ランタイムリファレンスで明示的に述べられています。


5
私のグーグルフーをブラッシュアップする必要があります。それがまさに私が探していた(またはそうではなかった)ものでした。
craigb 2008

さて、数日前にObjective-C 2.0のドキュメントを読んだので、ブックマークにリンクが飛び交っていました。
Torsten Marek

40

XCodeのドキュメントによると、あなたの擬似コードは基本的にそれを正しく理解しています。

@selector()ディレクティブを使用して、コンパイル時にSEL変数に値を割り当てるのが最も効率的です。ただし、場合によっては、プログラムが実行時に文字列をセレクタに変換する必要があります。これは、NSSelectorFromString関数で実行できます。

setWidthHeight = NSSelectorFromString(aBuffer);

編集:残念、遅すぎる。:P


2
NSStringFromSelector(@"doWork")それを逆に変換します(ちょうどfyi)
bendytree '30 / 01/30

8
NSStringFromSelector(@selector(doWork))
jpswain

そして、そのセレクターはおそらく何をしますか?ブロックか何かを指定すべきではないでしょうか?
user4951

12

以前の回答者の回答が示唆するよりも少し複雑あると言う必要があります...本当にセレクタ作成したい場合は、単に「呼び出し」だけでなく、「レイアウト」しているだけです。 。

「新しい」メソッドから呼び出される関数ポインタを作成する必要があります。そのため、などのメソッドの場合[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 return、object caller、object argument)とともにクラスに追加します。

 class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");

この種類の実行時の不正行為の良い例が、私のリポジトリの1つにあります。


5

私はこれがずっと前に回答されたことを知っていますが、それでも共有したいと思います。これはsel_registerNameあまりにも使用して行うことができます。

質問のサンプルコードは、次のように書き換えることができます。

SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];

2
実際にNSSelectorFromStringは、@ torsten-marekが内部で使用sel_registerNameしていることで言及されています。appledev「NSSelectorFromStringはaSelectorNameのUTF-8エンコードされた文字表現をsel_registerNameに渡し、その関数によって返された値を返します」
PLG
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.