2010-12-29 14 views
5

¿Cómo se llama a un método @selector con múltiples argumentos?@selector con múltiples argumentos

Tengo el siguiente

[self performSelector:@selector(changeImage:withString:) withObject:A1 withObject:fileString2 afterDelay:0.1]; 

pero consigo un selector no reconocido

enviado a instancia

error

Mi método que estoy llamando es el siguiente

-(void) changeImage: (UIButton *) button withString: (NSString *) string 
{ 
[button setImage:[UIImage imageNamed:string] forState:UIControlStateNormal]; 
} 

Respuesta

18

Debe utilizar NSInvocation

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: 
          [self methodSignatureForSelector:@selector(changeImage:withString:)]]; 
[invocation setTarget:self]; 
[invocation setSelector:@selector(changeImage:withString:)]; 
[invocation setArgument:A1 atIndex:2]; 
[invocation setArgument:fileString2 atIndex:3]; 
[NSTimer scheduledTimerWithTimeInterval:0.1f invocation:invocation repeats:NO]; 
+0

Genial, gracias. ¿Cómo lo llamo? Quiero llamar esto en muchos lugares. Entonces, ¿puede declararse en el método viewDidLoad y luego invocarse en varios lugares? – jarryd

+0

Realmente no entiendo lo que quieres decir. Puede poner este fragmento de código en cualquier lugar de la clase donde se define changeImage: withString :. Si desea llamarlo varias veces, debe envolverlo en un método y llamar a ese método en su lugar. – Jilouc

+1

alternativamente, puede hacer '[invocation performSelector: @selector (invoke) withObject: nil afterDelay: 0.1];' – user102008

0

Está llamando al performSelector:withObject:withObject:afterDelay:, pero ese método no existe.

Su única opción es performSelector:withObject:withObject:, pero no puede especificar un retraso con ese método. Si necesita un retraso, probablemente tenga que crear una categoría para NSObject y crear un nuevo método usted mismo.

4

clase El NSObject tiene un método performSelector:withObject:afterDelay:, y el protocolo NSObject especifica un método performSelector:withObject:withObject:, pero en ninguna parte hay especificado un performSelector:withObject:withObject:afterDelay:.

En este caso, tendrá que usar un NSInvocation para obtener la funcionalidad que desee. Configure la invocación, y luego puede llamar al performSelector:withObject:afterDelay en la invocación misma, utilizando el selector invoke y un objeto nil.

1

No es una buena manera de conseguir alrededor de él, pero si quería que podría modificar el método para aceptar una NSArray, cuando el objeto en el índice 0 es el botón y al el índice 1 es la cadena.

3

No hay un método para realizar un selector con múltiples argumentos y un retraso. Usted puede envolver el botón y el objeto de cadena en un NSDictionary para evitar este como esto:

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:A1,@"button",fileString2,@"string",nil]; 
[self performSelector:@selector(changeWithDict:) withObject:dict afterDelay:0.1]; 
//... 

-(void)changeWithDict:(NSDictionary *)dict { 
    [[dict objectForKey:@"button"] setImage:[UIImage imageNamed:[dict objectForKey:@"string"]] forState:UIControlStateNormal]; 
} 
2

Si usted está apuntando iOS 4.0+ usted podría utilizar bloques. Algo en la línea de esto debería hacer el truco.

// Delay execution of my block for 0.1 seconds. 
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, USEC_PER_SEC/10ull), dispatch_get_current_queue(), ^{ 
    [self changeImage:A1 withString:fileString2]; 
}); 
+0

Lo tendré en cuenta, pero estoy apuntando desde 3.0. – jarryd

+0

En ese caso, debe utilizar el método NSInvocation proporcionado por otros. Los bloques solo se introdujeron en iOS 4.0. – extremeboredom

Cuestiones relacionadas