web-dev-qa-db-ja.com

パラメーターを持つメソッド名からセレクターを作成する

現在のオブジェクトからSELを取得するコードサンプルがあります。

SEL callback = @selector(mymethod:parameter2);

そして、私は次のような方法を持っています

 -(void)mymethod:(id)v1 parameter2;(NSString*)v2 {
}

ここで、mymethodを別のオブジェクト、たとえばmyDelegateに移動する必要があります。

私が試してみました:

SEL callback = @selector(myDelegate, mymethod:parameter2);

しかし、コンパイルはしません。

57
BlueDolphin

SELは、Objective-Cのセレクターを表すタイプです。 @selector()キーワードは、説明したSELを返します。これは関数ポインターではなく、オブジェクトやあらゆる種類の参照を渡すことはできません。セレクター(メソッド)の各変数について、@ selectorの呼び出しでそれを表す必要があります。例えば:

-(void)methodWithNoParameters;
SEL noParameterSelector = @selector(methodWithNoParameters);

-(void)methodWithOneParameter:(id)parameter;
SEL oneParameterSelector = @selector(methodWithOneParameter:); // notice the colon here

-(void)methodWIthTwoParameters:(id)parameterOne and:(id)parameterTwo;
SEL twoParameterSelector = @selector(methodWithTwoParameters:and:); // notice the parameter names are omitted

通常、セレクターはデリゲートメソッドとコールバックに渡され、コールバック中に特定のオブジェクトで呼び出されるメソッドを指定します。たとえば、タイマーを作成すると、コールバックメソッドは特に次のように定義されます。

-(void)someMethod:(NSTimer*)timer;

したがって、タイマーをスケジュールするときは、@ selectorを使用して、オブジェクトのどのメソッドが実際にコールバックを担当するかを指定します。

@implementation MyObject

-(void)myTimerCallback:(NSTimer*)timer
{
    // do some computations
    if( timerShouldEnd ) {
      [timer invalidate];
    }
}

@end

// ...

int main(int argc, const char **argv)
{
    // do setup stuff
    MyObject* obj = [[MyObject alloc] init];
    SEL mySelector = @selector(myTimerCallback:);
    [NSTimer scheduledTimerWithTimeInterval:30.0 target:obj selector:mySelector userInfo:nil repeats:YES];
    // do some tear-down
    return 0;
}

この場合、オブジェクトobjが30秒ごとにmyTimerCallbackでメッセージ送信されるように指定しています。

100
Jason Coco

@selector()でパラメーターを渡すことはできません。

コールバックを実装しようとしているようです。これを行う最良の方法は、次のようなものです。

[object setCallbackObject:self withSelector:@selector(myMethod:)];

次に、オブジェクトのsetCallbackObject:withSelector:メソッドで、コールバックメソッドを呼び出すことができます。

-(void)setCallbackObject:(id)anObject withSelector:(SEL)selector {
    [anObject performSelector:selector];
}
18
Grant Limberg

セレクターについて既に述べられていることを超えて、NSInvocationクラスを調べてください。

NSInvocationは、静的にレンダリングされるObjective-Cメッセージです。つまり、オブジェクトに変換されるアクションです。 NSInvocationオブジェクトは、主にNSTimerオブジェクトと分散オブジェクトシステムによって、オブジェクト間およびアプリケーション間でメッセージを保存および転送するために使用されます。

NSInvocationオブジェクトには、Objective-Cメッセージのすべての要素(ターゲット、セレクター、引数、戻り値)が含まれます。これらの各要素は直接設定でき、戻り値はNSInvocationオブジェクトがディスパッチされると自動的に設定されます。

特定の状況では便利ですが、コーディングの通常の日にはNSInvocationを使用しないことに注意してください。 2つのオブジェクトを相互に通信させようとしている場合は、非公式または正式なデリゲートプロトコルを定義するか、既に述べたようにセレクターとターゲットオブジェクトを渡すことを検討してください。

5