Objective-C Language
Blocks
Zoeken…
Syntaxis
// Verklaar als lokale variabele:
returnType (^ blockName) (parameterType1, parameterType2, ...) = ^ returnType (argument1, argument2, ...) {...};
// Verklaar als een eigenschap:
@property (nonatomic, copy, nullability) returnType (^ blockName) (parameterTypes);
// Verklaar als methode parameter:
- (void) someMethodThatTakesABlock: (returnType (^ nullability) (parameterTypes)) blockName;
// Verklaar als argument voor een methodeaanroep:
[someObject someMethodThatTakesABlock: ^ returnType (parameters) {...}];
// Verklaar als een typefef:
typedef returnType (^ TypeName) (parameterTypes);
TypeName blockName = ^ returnType (parameters) {...};
// Declareer een C-functie retourneer een blokobject:
BLOCK_RETURN_TYPE (^ functienaam (functieparameters)) (BLOCK_PARAMETER_TYPE);
Opmerkingen
Blokken worden gespecificeerd door de taalspecificatie voor blokken voor C, Objective-C, C ++ en Objective-C ++.
Bovendien wordt de Blokken-ABI bepaald door de Blok-implementatiespecificatie .
Blokken als methode parameters
- (void)methodWithBlock:(returnType (^)(paramType1, paramType2, ...))name;
Definiëren en toewijzen
Een blok dat de toevoeging van twee dubbele precisienummers uitvoert, toegewezen aan de variabele addition
:
double (^addition)(double, double) = ^double(double first, double second){
return first + second;
};
Het blok kan vervolgens zo worden genoemd:
double result = addition(1.0, 2.0); // result == 3.0
Blokken als eigenschappen
@interface MyObject : MySuperclass
@property (copy) void (^blockProperty)(NSString *string);
@end
Bij het toewijzen, omdat self
blockProperty
behoudt, mag block geen sterke verwijzing naar self bevatten. Die wederzijdse sterke referenties worden een "bewaarcyclus" genoemd en voorkomen dat beide objecten worden vrijgegeven.
__weak __typeof(self) weakSelf = self;
self.blockProperty = ^(NSString *string) {
// refer only to weakSelf here. self will cause a retain cycle
};
Het is zeer onwaarschijnlijk, maar self
kan binnen het blok worden toegewezen, ergens tijdens de uitvoering. In dit geval wordt weakSelf
nil
en hebben alle berichten ervoor geen gewenst effect. Hierdoor kan de app in een onbekende staat achterblijven. Dit kan worden vermeden door weakSelf
met een __strong
tijdens __strong
en daarna op te ruimen.
__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;
};
Typedefs blokkeren
typedef double (^Operation)(double first, double second);
Als u een bloktype als een typedef declareert, kunt u de nieuwe typenaam gebruiken in plaats van de volledige beschrijving van de argumenten en retourwaarden. Dit definieert Operation
als een blok dat twee dubbele neemt en een dubbele teruggeeft.
Het type kan worden gebruikt voor de parameter van een methode:
- (double)doWithOperation:(Operation)operation
first:(double)first
second:(double)second;
of als een variabel type:
Operation addition = ^double(double first, double second){
return first + second;
};
// Returns 3.0
[self doWithOperation:addition
first:1.0
second:2.0];
Zonder de typedef is dit veel rommeliger:
- (double)doWithOperation:(double (^)(double, double))operation
first:(double)first
second:(double)second;
double (^addition)(double, double) = // ...
Blokkeert als lokale variabelen
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
Hier is een voorbeeld zonder retour en zonder parameters:
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