93

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

私は何ができますか:

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

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

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

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

4

4 に答える 4

180

私は Objective-C プログラマーではなく、ただのシンパサイザーですが、NSSelectorFromStringが必要なのかもしれません。これを使用して文字列をセレクターに変換できることは、 Runtime Referenceで明示的に言及されています。

于 2008-09-22T00:34:43.403 に答える
40

XCodeのドキュメントによると、あなたの疑似コードは基本的に正しくなります。

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

setWidthHeight = NSSelectorFromString(aBuffer);

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

于 2008-09-22T00:42:32.433 に答える
13

以前の回答者の回答が示唆するよりも少し複雑であると言わざるを得ません...本当にセレクターを作成したいのであれば...単に「置いてある」「1つを呼び出す」だけではありません.. .

「新しい」メソッドによって呼び出される関数ポインターを作成する必要があります..そのため、のようなメソッドの場合、次のよう[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 つ (こちら) で見ることができます。

于 2014-02-01T05:52:10.330 に答える