objective objective-c syntax objective-c-blocks

objective-c - block in objective c



Lista de sintaxis de la declaración de bloque (7)

Lista de sintaxis de declaración de bloque

A lo largo de

  • return_type sea ​​el tipo de objeto / primitivo / etc. te gustaría volver (comúnmente void )
  • blockName sea ​​el nombre variable del bloque que está creando
  • var_type es el tipo de objeto / primitivo / etc. le gustaría pasar como argumento (dejar en blanco para no parámetros)
  • varName es el nombre de la variable del parámetro dado

Y recuerda que puedes crear tantos parámetros como quieras.

Bloques como variables

Posiblemente la más común de declaración.

return_type (^blockName)(var_type) = ^return_type (var_type varName) { // ... };

Bloques como propiedades

Al igual que declarar bloques como variables, aunque sean sutilmente diferentes.

@property (copy) return_type (^blockName) (var_type);

Bloques como parámetros

Tenga en cuenta que esto es distinto de "Bloques como argumentos"; en este caso, está declarando un método que quiere un argumento de bloqueo.

- (void)yourMethod:(return_type (^)(var_type))blockName;

Bloques como argumentos

Tenga en cuenta que esto es distinto de "Bloques como parámetros"; en este caso, está llamando a un método que quiere un argumento de bloqueo con un bloque anónimo. Si ya ha declarado una variable de bloque, es suficiente pasar el nombre de la variable como argumento.

[someObject doSomethingWithBlock: ^return_type (var_type varName) { //... }];

Bloque anónimo

Esto es funcionalmente un bloque anónimo, sin embargo, la sintaxis para asignar bloques a las variables es simplemente establecer la variable igual a un bloque anónimo.

^return_type (var_type varName) { //... };

bloque de typedef

Esto le permite configurar un nombre corto al que se puede hacer referencia como cualquier otro nombre de clase durante la declaración de bloques.

typedef return_type (^blockName)(var_type);

Para luego usar blockName lugar de la sintaxis de la declaración de bloque estándar, simplemente sustitúyalo.

Bloque en linea

Esta es posiblemente una utilización menos útil de los bloques, pero aún así puede tener su lugar. Un bloque en línea es un bloque anónimo llamado inmediatamente después de la instanciación.

^return_type (var_type varName) { //... }(var);

Los bloques en línea son principalmente útiles para la compensación de alcance, y son aproximadamente equivalentes a simples fragmentos de código delimitados por llaves.

{ //... }

Bloques recursivos

Esto le permite llamar a un bloque desde sí mismo, creando un bucle que se puede utilizar durante las devoluciones de llamada y las llamadas GCD. Este método de creación de instancias está libre de ciclos de retención en ARC.

__block return_type (^blockName)(var_type) = [^return_type (var_type varName) { if (returnCondition) { blockName = nil; return; } // ... } copy]; blockName(varValue);

Bloques que regresan

Un método puede devolver un bloque,

- (return_type(^)(var_type))methodName { // ... }

Como puede una función, aunque un poco extraño.

return_type (^FunctionName())(var_type) { // ... }

Addendums

Si me he perdido algo, hágamelo saber en los comentarios y los investigaré / agregaré.

Ah, y en Swift ...

blockName = (varName: var_type) -> (return_type)

Es casi como si fuera una característica del lenguaje.

La sintaxis de bloque en el Objetivo C (y de hecho C, supongo) es notoriamente incongruente. Pasar bloques como argumentos se ve diferente a declarar bloques como ivars, que se ve diferente a bloques tipográficos.

¿Existe una lista completa de sintaxis de declaración de bloques que podría tener a mano para una referencia rápida?


Escribí un Bloqueo de finalización para una clase que devolverá los valores de un dado después de que se hayan sacudido:

  1. Defina typedef con returnType ( .h sobre la declaración de @interface )

    typedef void (^CompleteDiceRolling)(NSInteger diceValue);

  2. Definir una @property para el bloque ( .h )

    @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;

  3. Definir un método con finishBlock ( .h )

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;

  4. Inserte el método definido anteriormente en el archivo .m y finishBlock en @property definido antes

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{ self.completeDiceRolling = finishBlock; }

  5. Para activar el completionBlock bloqueo pase el tipo de variable predefinido (no olvide verificar si existe el bloqueo de completionBlock )

    if( self.completeDiceRolling ){ self.completeDiceRolling(self.dieValue); }


La biblioteca de fragmentos de código Xcode 4 contiene plantillas para las definiciones de bloque y bloques en línea como variables. También están disponibles mediante autocompletado ( typedefblock e inlineblock ).

Para bloques como argumentos a métodos, recomiendo declarar un typedef y luego simplemente usar eso. Hace que el código sea mucho más fácil de leer.


Personalmente, me gusta usar este sitio web ( http://fuckingblocksyntax.com ). El nombre es más fácil de recordar que la propia sintaxis de bloque:

http://fuckingblocksyntax.com

y si no puede cargar URL con malas palabras, puede usar este espejo: goshdarnblocksyntax.com


Si necesita volver a trabajar en Xcode 4.2, también puede sintetizar un bloque declarado como una propiedad al igual que lo haría con una propiedad que no es de bloque. No dejes que la sintaxis de bloque te lance.

Si su propiedad de bloque es esto:

@property (copy) return_type (^blockName) (var_type);

Entonces tu @sintetizar es esto:

@property blockName;

Aclamaciones.


Typedef:

typedef void (^block)(NSString *arg);

En línea:

void (^block)(NSString *) = ^(NSString *param) { // do something.... };

Método:

- (void)method:(void (^)(NSString *param))handler


typedef void (^OkBtnBlock)(id data); typedef void (^CancelBtnBlock)(); @property (nonatomic, strong) OkBtnBlock okBtnBlock; @property (nonatomic, strong) CancelBtnBlock cancelBtnBlock; + (void)foo:(OkBtnBlock)okBtn andCancel:(CancelBtnBlock)btnCancel;