メソッドディスパッチテーブルをセットアップしたいのですが、Objective-C でメソッドへのポインターを作成できるかどうか疑問に思っています (C の関数へのポインターのように)。いくつかの Objective-C ランタイム関数を使用してメソッドを動的に切り替えようとしましたが、問題はすべてのインスタンスに影響することです。
私はObjective-Cに非常に慣れていないので、例を示していただければ幸いです。
メソッドディスパッチテーブルをセットアップしたいのですが、Objective-C でメソッドへのポインターを作成できるかどうか疑問に思っています (C の関数へのポインターのように)。いくつかの Objective-C ランタイム関数を使用してメソッドを動的に切り替えようとしましたが、問題はすべてのインスタンスに影響することです。
私はObjective-Cに非常に慣れていないので、例を示していただければ幸いです。
Objective-C のメソッドは s と呼ばれ、データ型selector
で表されます。SEL
オブジェクトが から継承している場合NSObject
、次のようにセレクターを実行する (つまり、メソッドを呼び出す) ようにオブジェクトに指示できます。
SEL selector = @selector(doSomething:);
[obj performSelector:selector withObject:argument];
これは、次のようなメソッドが定義されていることを前提としています。
-(void)doSomething:(MyObject*)arg;
セレクターは、保持したいメソッドの名前を取るキーワードSEL
によってデータ型に割り当てられます。@selector
メソッドの名前は、すべての引数を取り除いたメソッド名です。例えば:
-(void)doSomething:(MyObject*)arg withParams:(MyParams*)params
として参照され@selector(doSomething:withParams:)
ます。
はい!Objective-C では、関数ポインターはセレクターと呼ばれます。次のように定義されたメソッドがある場合:
- (void)myFunctionWithObject:(NSObject*)obj otherObject:(NSNumber*)obj2
{
}
セレクターは次のように宣言されます。
@selector(myFunctionWithObject:otherObject:)
オブジェクトでセレクターを実行するには、以下を使用できます。
[object performSelector:@selector(myFunction)];
また
[object performSelector:@selector(myFunctionTakingParameter:) withObject: o];
セレクター データ型は、スレッドとタイマーに特に役立ちます。スレッドをディスパッチし、呼び出したいメッセージへのセレクターを提供できます。セレクターの配列 (またはディスパッチ テーブル) を作成する必要がある場合、または複数のパラメーターでセレクターを呼び出す必要がある場合は、NSInvocation クラスを使用できます。セレクターのラッパーを提供し、実際の引数を指定できるようにします。
Objective-C はすでに完全に動的なメソッド ディスパッチ テーブルに基づいていることに注意してください。ただし、関数への参照が必要なだけの場合は、セレクターを使用して関数ポインターを維持するとうまくいくようです。