Ce que vous trouverez dans ces notes.

Notes et astuces Objective C No Comments »

Je publie(rai) des notes brèves et astuces avancées à usages des développeurs mobiles utilisant le IOS SDK.

Share

Comment différer l’invocation d’un bloc en Objective C ?

Notes et astuces Objective C No Comments »

Vous savez très certainement différer l’invocation d’un sélecteur (méthode d’un objet Objective C) en utilisant les méthodes  dédiées de NSObject. performSelector:withObject:afterDelay

Par exemple :

1
[self performSelector:@selector(display:) withObject:myChain afterDelay:1];

“performSelector:withObject:afterDelay” ne peut pas invoquer :

  • Une méthode comportant un type différent de NSObject. (Ligne 1 du code ci-dessous)
  • Une méthode comportant plusieurs argument (Lignes 2 à 3)
1
2
3
-(void)doSomethingWithBool:(BOOL)shouldDoThat;
-(void)doSomethingWithFirstArgument:(NSString*)firstString 
                  andSecondArgument:(NSString*)secondString;

Il conviendrait de pouvoir différer l’exécution d’un bloc de code arbitraire, comportant un ou des appels différés. Comment différer l’exécution d’un bloc ?

Solution :

Nous allons utiliser Grand Central Dispatch (GCD) pour différer l’exécution d’un bloc. (cette solution est compatible avec IOS 4.x et plus)

1
2
3
4
5
6
7
   int delay=1; // Délai en secondes 
   dispatch_after( dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC),
                   dispatch_get_current_queue(), ^{
       // Le "bloc" à exécuter 
       [self doSomethingWithBool:NO];
       [self doSomethingWithFirstArgument:@"one" andSecondArgument:@"two"];
    });

Création d’une méthode générique pour différer l’exécution d’un bloc :

1
2
3
4
- (void)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay {
   dispatch_after( dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC),
                  dispatch_get_current_queue(),block);
}

Exemple d’invocation :

1
2
3
  [self performBlock:^{
       [self doSomethingWithFirstArgument:@"one" andSecondArgument:@"two"];
    } afterDelay:0];

Que se passe-t’il si nous nous utilisons un délai == 0 ?
Le code est exécuté immédiatement à la fin de la pile d’exécution (“run loop”)

Vous pouvez si vous le souhaitez créer une catégorie NSObject+Blocks pour intégrer cette méthode au comportement standard des NSObject. Pour ma part je préfère utiliser un singleton utilitaire pour ce type de tâche.

Share