Objective-C Language
ブロック
サーチ…
構文
//ローカル変数として宣言します:
returnType(^ blockName)(parameterType1、parameterType2、...)= ^ returnType(argument1、argument2、...){...};
//プロパティとして宣言します:
@property(非構造、コピー、NULL可能性)returnType(^ blockName)(parameterTypes);
//メソッドのパラメータとして宣言します:
- (void)someMethodThatTakesABlock:(returnType(^ nullability)(parameterTypes))blockName;
//メソッド呼び出しの引数として宣言する:
[someObject someMethodThatTakesABlock:^ returnType(parameters){...}];
// typedefとして宣言します:
typedef returnType(^タイプ名)(parameterTypes);
タイプ名blockName = ^ returnType(parameters){...};
// C関数を宣言してブロックオブジェクトを返す:
BLOCK_RETURN_TYPE(^ function_name(関数パラメータ))(BLOCK_PARAMETER_TYPE);
備考
メソッドパラメータとしてのブロック
- (void)methodWithBlock:(returnType (^)(paramType1, paramType2, ...))name;
定義と割当
変数addition
に割り当てられた2つの倍精度数値の加算を実行するブロック。
double (^addition)(double, double) = ^double(double first, double second){
return first + second;
};
ブロックは後で次のように呼び出すことができます:
double result = addition(1.0, 2.0); // result == 3.0
プロパティとしてのブロック
@interface MyObject : MySuperclass
@property (copy) void (^blockProperty)(NSString *string);
@end
blockProperty
とき、 self
はblockProperty
保持するblockProperty
、ブロックは自己への強い参照を含むべきではありません。それらの相互に強い参照は、「保持サイクル」と呼ばれ、いずれかのオブジェクトの解放を防ぎます。
__weak __typeof(self) weakSelf = self;
self.blockProperty = ^(NSString *string) {
// refer only to weakSelf here. self will cause a retain cycle
};
非常にありそうもないですが、実行中のどこかで、ブロック内でself
割り当てが解除される可能性があります。この場合、 weakSelf
はnil
なり、それに対するすべてのメッセージには効果がありません。これにより、アプリが未知の状態になることがあります。これは、保持することにより回避することができweakSelf
で__strong
ブロック実行中にIVAR、その後クリーンアップ。
__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;
};
typedefをブロックする
typedef double (^Operation)(double first, double second);
ブロック型をtypedefとして宣言すると、引数と戻り値の完全な説明の代わりに新しい型名を使用できます。これは、 Operation
を2つのdoubleを取り、doubleを返すブロックとして定義します。
型は、メソッドのパラメータとして使用できます。
- (double)doWithOperation:(Operation)operation
first:(double)first
second:(double)second;
または可変型として:
Operation addition = ^double(double first, double second){
return first + second;
};
// Returns 3.0
[self doWithOperation:addition
first:1.0
second:2.0];
typedefがなければ、これははるかに面倒です:
- (double)doWithOperation:(double (^)(double, double))operation
first:(double)first
second:(double)second;
double (^addition)(double, double) = // ...
ローカル変数としてのブロック
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
ここでは、戻り値なしのパラメータがない例を示します。
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