Objective-C: Utilisation des Blocks

vendredi 3 avril 2015

Pour rappel, les blocks sont des segments de code qui peuvent être passé en arguments de fonctions et de méthodes comme des valeurs.
Voici les différentes synthaxes de ce principe.

Le ^ représente la notion de block

^{
NSLog(@"This is a block");
}

Voici un exemple de block avec des arguments et une valeur de retour

double (^multiplyTwoValues)(double, double) =
  ^(double firstValue, double secondValue) {
    return firstValue * secondValue;
  }; 

double result = multiplyTwoValues(2,4);
NSLog(@"The result is %f", result);

L’autre avantage des blocks aussi est que les variables définies avant sont accessibles dans le block aussi.

int anInteger = 42;
 
void (^testBlock)(void) = ^{
   NSLog(@"Integer is: %i", anInteger);
}; 

anInteger = 84;
 
testBlock();

Dans ce cas-ci, il affichera 42.

Attention: il n’est pas possible de modifier la valeur de la variable anInteger dans le block!
Pour cela, il faut utiliser le paramètre __block variable

__block int anInteger = 42;
 
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
    };
 
    anInteger = 84;
 
    testBlock();

Par contre dans ce cas-ci, il affichera 84.

Il est aussi possible de modifier le contenu de la variable avec __block

__block int anInteger = 42;
 
void (^testBlock)(void) = ^{
   NSLog(@"Integer is: %i", anInteger);
   anInteger = 100;
};
 
testBlock();
NSLog(@"Value of original variable is now: %i", anInteger);

Résultat:

Integer is: 42
Value of original variable is now: 100

Mais le principale avantage de ces blocks est de pouvoir les faire passer par argument de nos fonctions:

[task beginTaskWithCallbackBlock:^{
   [self hideProgressIndicator];
}];

Concernant la déclaration de la méthode, il faut définir les arguments et valeur de retour.

- (void)doSomethingWithBlock:(void (^)(double, double))block {
    ...
    block(21.0, 2.0);
}

Dans ce cas-ci le block ne retourne rien mais a besoin de deux arguments.

Il est aussi recommandé de placer le block en dernier argument de la méthode

- (void)beginTaskWithName:(NSString *)name completion:(void(^)(void))callback;

Grâce à cette méthode, on sait simplifier pas mal notre code notamment concernant les fonctions dispatch ou schedule.

Tags: blocks , Objective C