Objective-C Language
Blöcke
Suche…
Syntax
// Als lokale Variable deklarieren:
returnType (^ blockName) (parameterType1, parameterType2, ...) = ^ returnType (Argument1, Argument2, ...) {...};
// Als Eigenschaft deklarieren:
@ property (nonatomic, copy, nullability) returnType (^ blockName) (parameterTypes);
// Deklarieren Sie als Methodenparameter:
- (void) someMethodThatTakesABlock: (returnType (^ nullability) (parameterTypes)) blockName;
// Deklarieren Sie als Argument für einen Methodenaufruf:
[someObject someMethodThatTakesABlock: ^ returnType (Parameter) {...}];
// Deklariere als typedef:
typedef returnType (^ TypeName) (parameterTypes);
Typname blockName = ^ returnType (Parameter) {...};
// Eine C-Funktion deklarieren, ein Blockobjekt zurückgeben:
BLOCK_RETURN_TYPE (^ Funktionsname (Funktionsparameter)) (BLOCK_PARAMETER_TYPE);
Bemerkungen
Blöcke werden in der Sprachspezifikation für Blöcke für C, Objective-C, C ++ und Objective-C ++ angegeben.
Zusätzlich wird die Blöcke ABI durch die definierte Block - Implementation Specification .
Blöcke als Methodenparameter
- (void)methodWithBlock:(returnType (^)(paramType1, paramType2, ...))name;
Definieren und Zuweisen
Ein Block, die Addition von zwei Zahlen mit doppelter Genauigkeit, zugewiesen variable führt addition
:
double (^addition)(double, double) = ^double(double first, double second){
return first + second;
};
Der Block kann anschließend so aufgerufen werden:
double result = addition(1.0, 2.0); // result == 3.0
Blöcke als Eigenschaften
@interface MyObject : MySuperclass
@property (copy) void (^blockProperty)(NSString *string);
@end
Bei der Zuweisung sollte block, da self
blockProperty
behält, keinen starken Verweis auf self enthalten. Diese gegenseitigen starken Referenzen werden als "Haltezyklus" bezeichnet und verhindern die Freigabe eines der Objekte.
__weak __typeof(self) weakSelf = self;
self.blockProperty = ^(NSString *string) {
// refer only to weakSelf here. self will cause a retain cycle
};
Es ist höchst unwahrscheinlich, aber das self
könnte innerhalb des Blocks irgendwo während der Ausführung freigegeben werden. In diesem Fall wird weakSelf
zu nil
und alle Nachrichten an ihn haben keine gewünschte Wirkung. Dadurch kann sich die App in einem unbekannten Zustand befinden. Dies kann durch die Beibehaltung vermieden werden weakSelf
mit einem __strong
Ivar während Blockausführung und aufzuräumen danach.
__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 blockieren
typedef double (^Operation)(double first, double second);
Wenn Sie einen Blocktyp als Typ deklarieren, können Sie anstelle der vollständigen Beschreibung der Argumente und Rückgabewerte den neuen Typnamen verwenden. Dies definiert Operation
als einen Block, der zwei Doubles benötigt und einen Double zurückgibt.
Der Typ kann für den Parameter einer Methode verwendet werden:
- (double)doWithOperation:(Operation)operation
first:(double)first
second:(double)second;
oder als Variablentyp:
Operation addition = ^double(double first, double second){
return first + second;
};
// Returns 3.0
[self doWithOperation:addition
first:1.0
second:2.0];
Ohne den Typedef ist das viel unordentlicher:
- (double)doWithOperation:(double (^)(double, double))operation
first:(double)first
second:(double)second;
double (^addition)(double, double) = // ...
Blöcke als lokale Variablen
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 ist ein Beispiel ohne Return und ohne Parameter:
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