セレクターで引数を渡す方法はありますか?
例:この方法があります
- (void)myMethod:(NSString*)value1 setValue2:(NSString*)value2{
}
2つの引数を渡すセレクターを介してこの関数を呼び出す必要があります。
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(/*my method*/) userInfo:nil repeats:YES];
これどうやってするの?
NSTimer
メソッドを使用できます:
_+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
invocation:(NSInvocation *)invocation
repeats:(BOOL)repeats;
_
代わりに、NSInvocation
オブジェクトを使用すると、引数を渡すことができます。 NSInvocation
オブジェクトは docs として定義されています:
静的にレンダリングされたObjective-Cメッセージ。つまり、オブジェクトに変換されるアクションです。
セレクターを使用してNSTimer
オブジェクトを作成する場合、次のメソッドの形式が必要です。
_- (void)timerFireMethod:(NSTimer*)theTimer
_
NSInvocation
を使用すると、ターゲット、セレクター、および渡す引数を設定できます。
_SEL selector = @selector(myMethod:setValue2:);
NSMethodSignature *signature = [MyObject instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:selector];
NSString *str1 = @"someString";
NSString *str2 = @"someOtherString";
//The invocation object must retain its arguments
[str1 retain];
[str2 retain];
//Set the arguments
[invocation setTarget:targetInstance];
[invocation setArgument:&str1 atIndex:2];
[invocation setArgument:&str2 atIndex:3];
[NSTimer scheduledTimerWithTimeInterval:0.1 invocation:invocation repeats:YES];
_
ここで、MyObject
は、_myMethod:setValue2:
_が宣言および実装されているクラスです。_instanceMethodSignatureForSelector:
_は、NSObject
に対して宣言されたNSMethodSignature
オブジェクトを返す便利な関数ですあなた、NSInvocation
に渡されます。
また、_setArgument:atIndex:
_では、セレクターとして設定されたメソッドに渡される引数のインデックスは、インデックス2から始まります。ドキュメントから:
インデックス0および1は、それぞれ非表示の引数selfおよび_cmdを示します。これらの値は、setTarget:およびsetSelector:メソッドを使用して直接設定する必要があります。通常メッセージで渡される引数には、インデックス2以上を使用してください。
scheduledTimerWithTimeInterval:
の場合、渡すセレクターに指定できる引数は1つだけです。さらに、その1つの引数はNSTimer *
オブジェクトでなければなりません。つまり、セレクターは次の形式をとる必要があります。
- (void)timerFireMethod:(NSTimer*)theTimer
あなたができることはuserInfo
辞書に引数を保存し、タイマーコールバックから必要なセレクターを呼び出すことです:
- (void)startMyTimer {
/* ... Some stuff ... */
[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(callMyMethod:)
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:someValue,
@"value1", someOtherValue, @"value2", nil]
repeats:YES];
}
- (void)callMyMethod:(NSTimer *)theTimer {
NSString *value1 = [[theTimer userInfo] objectForKey:@"value1"];
NSString *value2 = [[theTimer userInfo] objectForKey:@"value2"];
[self myMethod:value1 setValue2:value2];
}
ブロックの仕事のように見えます(これはSnow Leopardを対象としていると想定しています)。
-jcr
ブロックは今や明らかな答えのように見えます...しかし、クラシックランタイムでは非常にありふれた別のイディオムがあり、単一のオブジェクトで引数をピクルします。
- (void)doMyMethod:(NSDictionary *)userInfo
{
[self myMethod: [userInfo objectForKey:@"value1"] setValue2: [userInfo objectForKey:@"value2"]];
}
- (void)myMethod:(NSString*)value1 setValue2:(NSString*)value2{
}
今、あなたはに派遣することができます
[self performSelector:@selector(doMyMethod:) withObject:@{@"value1":@"value1",@"value2":@"value2"}];