web-dev-qa-db-fra.com

NSTimer avec fonction/bloc anonyme?

Je veux pouvoir planifier trois petits événements dans le futur sans avoir à écrire une fonction pour chacun. Comment puis-je faire cela en utilisant NSTimer? Je comprends que les blocs facilitent les fonctions anonymes, mais peuvent-ils être utilisés dans NSTimer et si oui, comment?

[NSTimer scheduledTimerWithTimeInterval:gameInterval  
         target:self selector:@selector(/* I simply want to update a label here */) 
         userInfo:nil repeats:NO];
40
Chris

Vous pouvez réellement appeler:

NSTimer.scheduledTimerWithTimeInterval(ti: NSTimeInterval,
                    target: AnyObject, 
                    selector: #Selector, 
                    userInfo: AnyObject?, 
                    repeats: Bool)

Utilisez-le comme ceci:

NSTimer.scheduledTimerWithTimeInterval(1, 
                    target: NSBlockOperation(block: {...}), 
                    selector: #selector(NSOperation.main), 
                    userInfo: nil, 
                    repeats: true)

24
Peter Peng

Vous pouvez utiliser dispatch_after si vous voulez obtenir quelque chose de similaire à NSTimer et bloquer l'exécution.

Voici l'exemple de code pour le même:

    int64_t delayInSeconds = gameInterval; // Your Game Interval as mentioned above by you

    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);

    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

        // Update your label here. 

    });

J'espère que cela t'aides.

56
Reno Jones

Une API de minuterie basée sur des blocs existe dans Cocoa (à partir de iOS 10+/macOS 10.12+) - voici comment l'utiliser dans Swift 3:

Timer(timeInterval: gameInterval, repeats: false) { _ in
    print("herp derp")
}

… Ou en Objective-C:

[NSTimer scheduledTimerWithTimeInterval:gameInterval repeats:NO block:^(NSTimer *timer) {
    NSLog(@"herp derp");
}];

Si vous devez cibler des versions de système d'exploitation antérieures à iOS10, macOS 12, tvOS 10, watchOS 3, vous devez utiliser l'une des autres solutions.

14
mz2

Version Objective-C de la réponse de @Peter Peng:

_actionDelayTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"Well this is useless.");
}] selector:@selector(main) userInfo:nil repeats:YES];
8
William Denniss

C'est assez facile, mais cela ne fait pas partie du framework Apple, du moins pas encore.

Vous pouvez écrire vous-même un wrapper à base de blocs pour NSTimer, par exemple. en utilisant GCD , ou vous pouvez utiliser des bibliothèques tierces existantes telles que celle-ci: https://github.com/jivadevoe/NSTimer-Blocks .

6
coverback

J'ai créé une catégorie sur NSTimer qui permet de l'utiliser avec des blocs.

https://github.com/mBrissman/NSTimer-Block

3
mBrissman

À la fin de 2018, vous le faites précisément comme ceci:

Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { timer in
  print("no, seriously, this works on iPhone")
} 

Ceci grâce à @JohnnyC!

Vraiment étrange!

 enter image description here

2
Fattie

J'aime ce hack @ Peter-Pang !! BlockOperation est créé à la volée, appartenant au minuteur qui lui-même appartient à la file d'attente en cours d'exécution, et appelle le sélecteur principal du bloc pour l'exécuter .... Sympa! !!

Mis à jour pour Swift 3

Timer.scheduledTimer(timeInterval: 1, target: BlockOperation { // ... }, selector: #selector(Operation.main), userInfo: nil, repeats: false)

0
Hugues BR