web-dev-qa-db-fra.com

Passage de paramètres à la méthode appelée par un NSTimer

Comment puis-je passer un paramètre à la méthode appelée par un NSTimer? Ma minuterie ressemble à ceci:

[NSTimer scheduledTimerWithTimeInterval:4 target:self selector:@selector(updateBusLocation) userInfo:nil repeats:YES];

et je veux pouvoir passer une chaîne à la méthode updateBusLocation. Aussi, où suis-je censé définir la méthode updateBusLocation? Dans le même fichier .m que je crée la minuterie?

MODIFIER:

En fait, j'ai toujours des problèmes. Je reçois le message d'erreur:

Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '* - [MapKitDisplayViewController updateBusLocation]: sélecteur non reconnu envoyé à l'instance 0x4623600'

Voici mon code:

- (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: Peu importe votre exemple de code fonctionne bien merci pour l'aide.

60
bubster

Vous devez définir la méthode dans la cible. Puisque vous définissez la cible sur 'self', alors oui, ce même objet doit implémenter la méthode. Mais vous auriez pu fixer la cible à tout ce que vous vouliez.

userInfo est un pointeur que vous pouvez définir sur n'importe quel objet (ou collection) de votre choix et qui sera transmis au sélecteur de cible lors du déclenchement du minuteur.

J'espère que cela pourra aider.

EDIT: ... Exemple simple:

Configurez la minuterie:

    NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:2.0 
                              target:self 
                              selector:@selector(handleTimer:) 
                              userInfo:@"someString" repeats:NO];

et implémentez le gestionnaire dans la même classe (en supposant que vous définissiez la cible à 'self'):

- (void)handleTimer:(NSTimer*)theTimer {

   NSLog (@"Got the string: %@", (NSString*)[theTimer userInfo]);

}
97
Firoze Lafeer

Vous pouvez passer vos arguments avec userInfo: [NSDictionary dictionaryWithObjectsAndKeys:parameterObj1, @"keyOfParameter1"];

Un exemple simple:

[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];
}
23
Oleh Kudinov

Pour Swift fais comme ça,

Par exemple, vous voulez envoyer UILabel avec 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

}
3
Zaid Pathan

Exemple supplémentaire dans Swift using Dictionnaire littéral pour passage de paramètres à la méthode appelée par 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)")
}
2
King-Wizard

Pour Swift 4.0:

Vous pouvez avoir une fonction avec les paramètres de votre choix et utiliser le bloc "scheduleTimer" pour exécuter le code que vous devez répéter.

func someFunction(param1: Int, param2: String) {

    let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
        print(param1)
        print(param2)
    }
}

Veillez à appeler timer.invalidate () lorsque vous avez terminé pour l’empêcher de fonctionner en continu.

0
George Leonidas

Ce n’est pas une réponse directe à la question, mais comme j’ai couru dans cette recherche et j’avais besoin de quelque chose de différent, cela pourrait aider quelqu'un. Je voulais appeler une fonction dans une classe d'assistance, que je devais transmettre dans la variable UIViewController, plutôt que de la transmettre à userinfo, ce qui ne me permettait pas d'appeler manuellement la fonction ailleurs. J'ai créé une autre fonction que le temporisateur appellerait fonction que je suis intéressé à partir de là. Une solution de contournement qui a aidé.

Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(self.timerFired), userInfo: nil, repeats:true);

func timerFired() {

myFunction(controller: self)

}
0
Sam Bing