Argumentos no @selector

Existe alguma maneira que eu possa passar argumentos no seletor?

exemplo: eu tenho esse método

- (void)myMethod:(NSString*)value1 setValue2:(NSString*)value2{ } 

e eu preciso chamar essa function através de um seletor passando dois argumentos.

 [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(/*my method*/) userInfo:nil repeats:YES]; 

Como posso fazer isso?

Você poderia usar o método NSTimer :

 + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds invocation:(NSInvocation *)invocation repeats:(BOOL)repeats; 

Em vez disso, uma vez que um object NSInvocation permitirá que você passe argumentos; um object NSInvocation é, como os documentos definem:

uma mensagem Objective-C é renderizada estática, ou seja, é uma ação transformada em um object.

Ao criar um object NSTimer usando um seletor, é necessário que o formato do método seja:

 - (void)timerFireMethod:(NSTimer*)theTimer 

Um NSInvocation permite que você defina o destino, o seletor e os argumentos que você passa:

 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]; 

Onde MyObject é a class que myMethod:setValue2: é declarada e implementada em – instanceMethodSignatureForSelector: é uma function de conveniência declarada em NSObject que retorna um object NSMethodSignature para você, a ser passado para NSInvocation .

Além disso, para observar, com setArgument:atIndex: os índices dos argumentos a serem passados ​​para o método definido como o seletor começam no índice 2. A partir dos documentos:

Índices 0 e 1 indicam os argumentos ocultos self e _cmd, respectivamente; você deve definir esses valores diretamente com os methods setTarget: e setSelector:. Use os índices 2 e maiores para os argumentos normalmente passados ​​em uma mensagem.

Para scheduledTimerWithTimeInterval: :, o seletor que você passa pode ter apenas um argumento. Além disso, seu um argumento deve ser um object NSTimer * . Em outras palavras, o seletor deve ter o seguinte formato:

 - (void)timerFireMethod:(NSTimer*)theTimer 

O que você poderia fazer é armazenar os argumentos no dictionary userInfo e chamar o seletor desejado no retorno de chamada do timer:

 - (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]; } 

Parece um trabalho para blocos (supondo que isso é direcionado para o Snow Leopard).

-jcr

blocos parecem ser uma resposta óbvia agora … mas há outro idioma que era muito comum no tempo de execução clássico, aprimore seus argumentos em um único object:

  - (void)doMyMethod:(NSDictionary *)userInfo { [self myMethod: [userInfo objectForKey:@"value1"] setValue2: [userInfo objectForKey:@"value2"]]; } - (void)myMethod:(NSString*)value1 setValue2:(NSString*)value2{ } 

agora você pode despachar para

 [self performSelector:@selector(doMyMethod:) withObject:@{@"value1":@"value1",@"value2":@"value2"}]; 
 @selector(myMethod:setValue2:) 

Já que o seletor para o seu método não é chamado apenas de myMethod mas sim myMethod:setValue2:

Também (e eu poderia estar fora da base aqui), eu acredito que tecnicamente você pode soltar as palavras entre dois pontos e, portanto, também usar @selector(myMethod::) mas não me cite sobre isso a menos que outros possam confirmá-lo.