Ricerca…


Sintassi

  • // Dichiara come variabile locale:

    returnType (^ blockName) (parameterType1, parameterType2, ...) = ^ returnType (argument1, argument2, ...) {...};

  • // Dichiara come una proprietà:

    @property (nonatomic, copy, nullability) returnType (^ blockName) (parameterTypes);

  • // Dichiara come parametro del metodo:

    - (void) someMethodThatTakesABlock: (returnType (^ nullability) (parameterTypes)) blockName;

  • // Dichiara come argomento una chiamata al metodo:

    [someObject someMethodThatTakesABlock: ^ returnType (parameters) {...}];

  • // Dichiara come typedef:

    typedef returnType (^ TypeName) (parameterTypes);

    TypeName blockName = ^ returnType (parameters) {...};

  • // Dichiara una funzione C restituisce un oggetto blocco:

    BLOCK_RETURN_TYPE (^ nome_funzione (parametri funzione)) (BLOCK_PARAMETER_TYPE);

Osservazioni

I blocchi sono specificati dalla specifica della lingua per i blocchi per C, Objective-C, C ++ e Objective-C ++.

Inoltre, l'ABI dei blocchi è definito dalla specifica di implementazione del blocco .

Blocchi come parametri del metodo

- (void)methodWithBlock:(returnType (^)(paramType1, paramType2, ...))name;

Definizione e assegnazione

Un blocco che esegue l'aggiunta di due numeri di precisione doppia, assegnati addition variabile:

double (^addition)(double, double) = ^double(double first, double second){
    return first + second;
};

Il blocco può essere successivamente chiamato in questo modo:

double result = addition(1.0, 2.0); // result == 3.0

Blocchi come proprietà

@interface MyObject : MySuperclass

@property (copy) void (^blockProperty)(NSString *string);

@end

Quando si assegna, dal momento che self blockProperty , il blocco non deve contenere un forte riferimento a self. Questi reciproci riferimenti forti sono chiamati "retain cycle" e impediscono il rilascio di entrambi gli oggetti.

__weak __typeof(self) weakSelf = self;
self.blockProperty = ^(NSString *string) {
    // refer only to weakSelf here.  self will cause a retain cycle
};

È altamente improbabile, ma il self potrebbe essere deallocato all'interno del blocco, da qualche parte durante l'esecuzione. In questo caso weakSelf diventa nil e tutti i messaggi ad esso non hanno alcun effetto desiderato. Questo potrebbe lasciare l'app in uno stato sconosciuto. Ciò può essere evitato mantenendo weakSelf con un __strong ivar durante l'esecuzione del blocco e ripulire in seguito.

__weak __typeof(self) weakSelf = self;
self.blockProperty = ^(NSString *string) {
    __strong __typeof(weakSelf) strongSelf = weakSelf;
    // refer only to strongSelf here.
    // ...
    // At the end of execution, clean up the reference
    strongSelf = nil;
};

Blocca typedef

typedef double (^Operation)(double first, double second);

Se si dichiara un tipo di blocco come typedef, è possibile utilizzare il nuovo nome del tipo anziché la descrizione completa degli argomenti e dei valori restituiti. Definisce l' Operation come un blocco che richiede due doppi e restituisce un doppio.

Il tipo può essere utilizzato per il parametro di un metodo:

- (double)doWithOperation:(Operation)operation 
                    first:(double)first 
                   second:(double)second;

o come tipo variabile:

Operation addition = ^double(double first, double second){
    return first + second;
};

// Returns 3.0
[self doWithOperation:addition
                first:1.0
               second:2.0];

Senza il typedef, questo è molto più confuso:

- (double)doWithOperation:(double (^)(double, double))operation
                    first:(double)first
                   second:(double)second;

double (^addition)(double, double) = // ...

Blocchi come variabili locali

returnType (^blockName)(parameterType1, parameterType2, ...) = ^returnType(argument1, argument2, ...) {...};    

float (^square)(float) = ^(float x) {return x*x;};

square(5); // resolves to 25
square(-7); // resolves to 49

Ecco un esempio senza restituzione e senza parametri:

NSMutableDictionary *localStatus;
void (^logStatus)() = ^(void){ [MYUniversalLogger logCurrentStatus:localStatus]};

// Insert some code to add useful status information
// to localStatus dictionary 

logStatus(); // this will call the block with the current localStatus


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow