Objective-C Language
Blocs
Recherche…
Syntaxe
// déclare comme variable locale:
returnType (^ blockName) (parameterType1, parameterType2, ...) = ^ returnType (argument1, argument2, ...) {...};
// déclare en tant que propriété:
@property (nonatomique, copie, nullité) returnType (^ blockName) (parameterTypes);
// Déclarez comme paramètre de méthode:
- (void) someMethodThatTakesABlock: (returnType (^ nullité) (parameterTypes)) blockName;
// Déclarer comme argument à un appel de méthode:
[someObject someMethodThatTakesABlock: ^ returnType (paramètres) {...}];
// déclare en tant que typedef:
typedef returnType (^ TypeName) (parameterTypes);
TypeName blockName = ^ returnType (paramètres) {...};
// Déclarer une fonction C renvoyer un objet bloc:
BLOCK_RETURN_TYPE (^ nom_fonction (paramètres de fonction)) (BLOCK_PARAMETER_TYPE);
Remarques
Les blocs sont spécifiés par la spécification de langage pour les blocs C, Objective-C, C ++ et Objective-C ++.
En outre, l’ABI des blocs est défini par la spécification d’implémentation de bloc .
Blocs en tant que paramètres de méthode
- (void)methodWithBlock:(returnType (^)(paramType1, paramType2, ...))name;
Définir et assigner
Un bloc qui effectue l'ajout de deux nombres à double précision, affectés à l' addition
variables:
double (^addition)(double, double) = ^double(double first, double second){
return first + second;
};
Le bloc peut ensuite être appelé comme ceci:
double result = addition(1.0, 2.0); // result == 3.0
Blocs en tant que propriétés
@interface MyObject : MySuperclass
@property (copy) void (^blockProperty)(NSString *string);
@end
Lors de l'attribution, puisque self
conserve blockProperty
, block ne doit pas contenir de référence forte à self. Ces références fortes mutuelles sont appelées "cycle de rétention" et empêchent la libération de l'un ou l'autre des objets.
__weak __typeof(self) weakSelf = self;
self.blockProperty = ^(NSString *string) {
// refer only to weakSelf here. self will cause a retain cycle
};
C'est très improbable, mais self
peut être désalloué à l'intérieur du bloc, quelque part pendant l'exécution. Dans ce cas, weakSelf
devient nil
et tous les messages ne présentent aucun effet souhaité. Cela pourrait laisser l'application dans un état inconnu. Cela peut être évité en conservant weakSelf
un __strong
weakSelf
avec un ivar __strong
lors de l'exécution du bloc et en __strong
par la suite.
__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;
};
Bloc Typedefs
typedef double (^Operation)(double first, double second);
Si vous déclarez un type de bloc en tant que typedef, vous pouvez utiliser le nouveau nom de type au lieu de la description complète des arguments et des valeurs de retour. Cela définit Operation
comme un bloc qui prend deux doubles et retourne un double.
Le type peut être utilisé pour le paramètre d'une méthode:
- (double)doWithOperation:(Operation)operation
first:(double)first
second:(double)second;
ou comme type de variable:
Operation addition = ^double(double first, double second){
return first + second;
};
// Returns 3.0
[self doWithOperation:addition
first:1.0
second:2.0];
Sans le typedef, c'est beaucoup plus compliqué:
- (double)doWithOperation:(double (^)(double, double))operation
first:(double)first
second:(double)second;
double (^addition)(double, double) = // ...
Blocs en tant que 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
Voici un exemple sans retour et sans paramètres:
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