Buscar..


Sintaxis

  • // Declarar como una variable local:

    returnType (^ blockName) (parametersType1, parametersType2, ...) = ^ returnType (argumento1, argumento2, ...) {...};

  • // Declarar como una propiedad:

    @propiedad (nonatomic, copy, nullability) returnType (^ blockName) (parametersTypes);

  • // Declarar como un parámetro del método:

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

  • // Declarar como un argumento a una llamada de método:

    [someObject someMethodThatTakesABlock: ^ returnType (parámetros) {...}];

  • // Declarar como un typedef:

    typedef returnType (^ TypeName) (parametersTypes);

    TypeName blockName = ^ returnType (parámetros) {...};

  • // Declarar una función en C devolver un objeto de bloque:

    BLOCK_RETURN_TYPE (^ function_name (parámetros de función)) (BLOCK_PARAMETER_TYPE);

Observaciones

Los bloques se especifican en la Especificación de lenguaje para bloques para C, Objective-C, C ++ y Objective-C ++.

Además, la ABI de bloques está definida por la Especificación de implementación de bloques .

Bloques como parámetros del método

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

Definiendo y Asignando

Un bloque que realiza la adición de dos números de doble precisión, asignados a la addition variables:

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

El bloque puede ser llamado posteriormente así:

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

Bloques como propiedades

@interface MyObject : MySuperclass

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

@end

Al asignar, dado que self conserva blockProperty , el bloque no debe contener una referencia fuerte a self. Esas referencias fuertes mutuas se denominan "ciclo de retención" y evitarán la liberación de cualquiera de los objetos.

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

Es muy poco probable, pero el self podría ser desasignado dentro del bloque, en algún lugar durante la ejecución. En este caso weakSelf vuelve nil y todos los mensajes no tienen el efecto deseado. Esto podría dejar la aplicación en un estado desconocido. Esto puede evitarse conservando weakSelf con un __strong ivar durante la ejecución del bloque y la limpieza posterior.

__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;
};

Bloquear Typedefs

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

Si declara un tipo de bloque como typedef, puede usar el nuevo nombre de tipo en lugar de la descripción completa de los argumentos y los valores de retorno. Esto define la Operation como un bloque que toma dos dobles y devuelve un doble.

El tipo se puede utilizar para el parámetro de un método:

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

o como un tipo de variable:

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

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

Sin el typedef, esto es mucho más desordenado:

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

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

Bloques como variables locales.

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

Aquí hay un ejemplo sin retorno y sin parámetros:

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow