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únmentevoid
) -
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:
Defina typedef con returnType (
.h
sobre la declaración de@interface
)typedef void (^CompleteDiceRolling)(NSInteger diceValue);
Definir una
@property
para el bloque (.h
)@property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
Definir un método con
finishBlock
(.h
)- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
Inserte el método definido anteriormente en el archivo
.m
yfinishBlock
en@property
definido antes- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{ self.completeDiceRolling = finishBlock; }
Para activar el
completionBlock
bloqueo pase el tipo de variable predefinido (no olvide verificar si existe el bloqueo decompletionBlock
)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;