Block

29 novembre 2017

Su Objective C, un block rappresenta una porzione di codice che possiamo salvare in una variabile, passare come parametro a un metodo o persino a un altro block.

Questi costrutti vengono utilizzati comunemente per gestire la programmazione asincrona (quando ad esempio vogliamo eseguire una certa azione al termine di un’animazione o di una chiamata remota).

Vediamo la sintassi:

^{
    NSLog(@"Hello Block!");
};

Come mostrato nell’esempio precedente. un blocco inizia con il simbolo ^ e poi contiene del codice arbitrario, racchiuso tra parentesi graffe.

Ecco un altro esempio:

^{
    int a = 10;
    int b = 20;
    int sum = a + b;
    NSLog(@"%d + %d = %d", a, b, sum);
};

Come dicevamo, un block può essere salvato in una variabile, che può essere definita come mostrato di seguito:

void (^firstBlock)(void);

Con questa sintassi abbiamo dichiarato una variabile avente nome firstBlock. Il tipo della variabile è un block che accetta 0 parametri (informazione che desumiamo dal void a destra) e non ritorna alcun valore (informazione che desumiamo dal void a sinistra).

Poiché la variabile (block con 0 parametri e void come tipo di ritorno) è compatibile con i blocchi che abbiamo definito in precedenza, possiamo salvare uno di quei blocchi dentro firstBlock:

void (^firstBlock)(void) = ^{
    int a = 10;
    int b = 20;
    int sum = a + b;
    NSLog(@"%d + %d = %d", a, b, sum);
};

Adesso firstBlock contiene effettivamente un block che calcola la somma di 10 e 20 e poi ne stampa il risultato. Per eseguire il block contenuto in firstBlock, scriviamo:

firstBlock();

Il risultato apparirà nella console di debug:

Parametri e tipo di ritorno

Un block può ricevere dei parametri e avere un certo tipo di ritorno diverso da void, così come accade per metodi e funzioni.

Scriviamo, ad esempio, un block che riceve due interi e ne ritorna uno come risultato:

int (^sum)(int, int) = ^ (int a, int b) {
    return a + b;
};

In questo caso abbiamo dichiarato una variabile sum. Il tipo è un block che accetta 2 int come parametri e ritorna un int. Abbiamo poi popolato la variabile con il codice che effettua la somma dei 2 parametri e li restituisce.

Ora possiamo testare il nostro blocco:

@import Foundation;

int main(int argc, const char * argv[]) {
    @autoreleasepool {


        int (^sum)(int, int) = ^ (int a, int b) {
            return a + b;
        };
        
        int result = sum(1, 2);
        NSLog(@"%d", result);
    }
    return 0;
}

Il risultato mostrato nella console sarà quindi 3.

Applicare un block agli elementi di un NSArray

I block possono anche essere utilizzati per applicare una certa porzione di codice a ogni elemento di una collection.

La classe NSArray, ad esempio, fornisce un metodo per applicare un block a ogni elemento dell’array.

Immaginiamo di avere questo array:

NSArray<NSString * > * languages = @[@"Objective-C", @"Java", @"Swift"];

Supponiamo di voler stampare la lunghezza di ogni stringa contenuta nell’array. Possiamo sfruttare un block come quello seguente:

        [languages enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
            NSUInteger length = [obj length];
            NSLog(@"%lu", (unsigned long)length);
            
        }];

Il codice precedente produce il seguente output:

11
4
5

Infatti, il block che abbiamo passato all’array languages (ovvero il codice che abbiamo scritto tra le parentesi graffe) è stato applicato automaticamente dalla classe NSArray a ogni elemento.

Tutte le lezioni

1 ... 22 23 24

 

 

1 ... 22 23 24

Se vuoi aggiornamenti su Block inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Block

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy