Objective-C Language
Blocks
Sök…
Syntax
// Förklara som en lokal variabel:
returnType (^ blockName) (parameterType1, parameterType2, ...) = ^ returnType (argument1, argument2, ...) {...};
// Förklara som en egendom:
@ egendom (icke-atomisk, kopia, nollbarhet) returnType (^ blockName) (parameterTypes);
// Förklara som metodparameter:
- (void) someMethodThatTakesABlock: (returnType (^ nullability) (parameterTypes)) blockName;
// Förklara som ett argument till ett metodsamtal:
[someObject someMethodThatTakesABlock: ^ returnType (parametrar) {...}];
// Förklara som typedef:
typedef returnType (^ TypeName) (parameterTypes);
Typnamn blockName = ^ returnType (parametrar) {...};
// Förklara att en C-funktion returnerar ett blockobjekt:
BLOCK_RETURN_TYPE (^ funktionsnamn (funktionsparametrar)) (BLOCK_PARAMETER_TYPE);
Anmärkningar
Block specificeras av språkspecifikationen för block för C, Objekt-C, C ++ och Objekt-C ++.
Dessutom definieras block ABI av Block Implementation Specification .
Blockerar som metodparametrar
- (void)methodWithBlock:(returnType (^)(paramType1, paramType2, ...))name;
Definiera och tilldela
Ett block som utför tillägg av två dubbla precisionsnummer, tilldelade variabel addition
:
double (^addition)(double, double) = ^double(double first, double second){
return first + second;
};
Därefter kan blocket kallas så:
double result = addition(1.0, 2.0); // result == 3.0
Blockerar som egenskaper
@interface MyObject : MySuperclass
@property (copy) void (^blockProperty)(NSString *string);
@end
Vid tilldelning, eftersom self
behåller blockProperty
, bör blocket inte innehålla en stark referens till jaget. Dessa ömsesidiga starka referenser kallas en "behållningscykel" och kommer att förhindra frigörandet av endera objektet.
__weak __typeof(self) weakSelf = self;
self.blockProperty = ^(NSString *string) {
// refer only to weakSelf here. self will cause a retain cycle
};
Det är mycket osannolikt, men self
kan omfördelas inuti kvarteret någonstans under avrättningen. I detta fall blir weakSelf
nil
och alla meddelanden till den har ingen önskad effekt. Detta kan lämna appen i okänt tillstånd. Detta kan undvikas genom att behålla weakSelf
med en __strong
ivar under körning av blocket och rensa upp därefter.
__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;
};
Block Typedefs
typedef double (^Operation)(double first, double second);
Om du förklarar en blocktyp som en typedef kan du sedan använda det nya typnamnet istället för den fullständiga beskrivningen av argumenten och returnvärdena. Detta definierar Operation
som ett block som tar två dubblar och ger en dubbel.
Typen kan användas för parametern för en metod:
- (double)doWithOperation:(Operation)operation
first:(double)first
second:(double)second;
eller som en variabel typ:
Operation addition = ^double(double first, double second){
return first + second;
};
// Returns 3.0
[self doWithOperation:addition
first:1.0
second:2.0];
Utan typefilen är detta mycket messier:
- (double)doWithOperation:(double (^)(double, double))operation
first:(double)first
second:(double)second;
double (^addition)(double, double) = // ...
Blockerar som lokala variabler
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
Här är ett exempel utan retur och inga parametrar:
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