objective c - Pasar parámetros al método llamado por un NSTimer
objective-c cocoa-touch (5)
¿Cómo puedo pasar un parámetro al método llamado por un NSTimer? Mi cronómetro se ve así:
[NSTimer scheduledTimerWithTimeInterval:4 target:self selector:@selector(updateBusLocation) userInfo:nil repeats:YES];
y quiero poder pasar una cadena al método updateBusLocation. Además, ¿dónde se supone que debo definir el método updateBusLocation? ¿En el mismo archivo .m que creo el temporizador?
EDITAR:
En realidad, todavía estoy teniendo problemas. Recibo el mensaje de error:
Aplicación de finalización debido a una excepción no detectada ''NSInvalidArgumentException'', razón: '' * - [MapKitDisplayViewController updateBusLocation]: selector no reconocido enviado a la instancia 0x4623600''
Aquí está mi código:
- (IBAction) showBus {
//do something
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateBusLocation) userInfo:txtFieldData repeats:YES];
[txtFieldData release];
}
- (void) updateBusLocation:(NSTimer*)theTimer
{
NSLog(@"timer method was called");
NSString *txtFieldData = [[NSString alloc] initWithString:(NSString*)[theTimer userInfo]];
if(txtFieldData == busNum.text) {
//do something else
}
}
EDIT # 2: No importa que su código de ejemplo funcione bien gracias por la ayuda.
Ejemplo adicional en Swift usando el literal del Diccionario para pasar parámetros al método llamado por NSTimer :
override func viewDidLoad() {
super.viewDidLoad()
let dictionary: [String : AnyObject] = ["first element" : "Jordan",
"second element" : Int(23)]
NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(0.41),
target: self,
selector: "foo:",
userInfo: dictionary,
repeats: false)
}
func foo(timer: NSTimer) {
let dictionary: [String : AnyObject] = timer.userInfo! as! [String : AnyObject]
let firstElement: String = dictionary["first element"] as! String
let secondElement: Int = dictionary["second element"] as! Int
print("/(firstElement) - /(secondElement)")
}
Necesitas definir el método en el objetivo. Dado que establece el objetivo como "uno mismo", entonces sí, ese mismo objeto necesita implementar el método. Pero podrías haber establecido el objetivo a cualquier otra cosa que quisieras.
userInfo es un puntero que puede establecer en cualquier objeto (o colección) que le guste y que se pasará al selector de destino cuando se dispare el temporizador.
Espero que ayude.
EDITAR: ... Ejemplo simple:
Configurar el temporizador:
NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(handleTimer:)
userInfo:@"someString" repeats:NO];
e implemente el controlador en la misma clase (suponiendo que está estableciendo el destino en ''self''):
- (void)handleTimer:(NSTimer*)theTimer {
NSLog (@"Got the string: %@", (NSString*)[theTimer userInfo]);
}
No es una respuesta directa a la pregunta, pero desde que me encontré con esto mientras buscaba y necesitaba algo diferente, puede ayudar a alguien. Quería llamar a un funciton en una clase de ayuda, que necesitaba pasar el UIViewController
, en lugar de pasarlo con la información de usuario que no me permitía llamar a la función manualmente en otro lugar. Creé otra función que el temporizador llamaba y llamaba función que me interesaba desde allí. Una solución que ayudó.
Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(self.timerFired), userInfo: nil, repeats:true);
func timerFired() {
myFunction(controller: self)
}
Para que Swift haga esto,
Por ejemplo, quiere enviar UILabel con NSTimer
override func viewDidLoad() {
super.viewDidLoad()
var MyLabel = UILabel()
NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("callMethod:"), userInfo: MyLabel, repeats: false)
}
func callMethod(timer:NSTimer){
var MyLabel:UILabel = timer.userInfo as UILabel
}
Puede pasar sus argumentos con userInfo: [NSDictionary dictionaryWithObjectsAndKeys:parameterObj1, @"keyOfParameter1"];
Un simple ejemplo:
[NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(handleTimer:)
userInfo:@{@"parameter1": @9}
repeats:NO];
- (void)handleTimer:(NSTimer *)timer {
NSInteger parameter1 = [[[timer userInfo] objectForKey:@"parameter1"] integerValue];
}