Objective-C block(ブロック)


blockブロックスーパーイメージ関数ポインタ
-構文
1.定義と使用
double (^multiplyTwoValues)(double, double) =
                              ^(double firstValue, double secondValue) {
                                  return firstValue * secondValue;
                              };
    double result = multiplyTwoValues(2,4);
    NSLog(@"The result is %f", result);

blockは、その環境にある変数の値、すなわち、
- (void)testMethod { int anInteger = 42; void (^testBlock)(void) = ^{ NSLog(@"Integer is: %i", anInteger); }; testBlock(); anInteger = 84; testBlock(); };

ただし、testBlock()を1回目に実行した結果は42であり、2回目は42であった.blockブロックが取得したのはanIntegerの値のコピーであり、デジタル定数42に相当する.2回目のtestBlock()の場合、出力値が84になるように、anIntegerをパラメータとしてblockに渡すことができます.または_を使用します.block(次の節を参照).
2. _block
        ,   anInteger      ,             。
_block int anInteger = 42;
void (^testBlock)(void) = ^{ 
    NSLog(@"Integer is: %i", anInteger); 
    anInteger = 84;
    NSLog(@"Integer is: %i", anInteger); 
};
    testBlock();

以上の運転結果は4284です.
3.ブロックは、パラメータとして関数またはメソッドに渡すことができる
ブロック(void(^)void)をパラメータとする方法を定義します.たとえば、次のようにします.
(void)beginTaskWithCallbackBlock:(void (^)(void))callbackBlock{
    …   
    callbackBlock();
};

ご利用の際は、匿名blockをご利用いただけます
[someObject beginTaskWithCallbackBlock:^{ doSomething; }];

1つのメソッドに複数のパラメータがある場合は、blockを最後のパラメータに配置することに注意してください.
4.typedefを使用してblockタイプを定義できますtypedef double (^OYSimpleBlock)(int,int *);はOYSimpleBlockを直接使用してこのタイプのblockを定義することができます.
OYSimpleBlock b=^(int a,int b){
    …
    return (double)a*b;
};

これは特に、パラメータもブロックのブロックであることを定義するときに役立ちます.
5.blockも一般的な変数のようにクラスの属性として使える
@interface OYClass : NSObject
@property (copy) void (^OYBlock)(int,int);
@end

一般的なプロパティと同様にポイント構文でアクセスできます
self.OYBlock=^(int a,int b){
    …
};
self.OYBlock();

6.blockでblock以外のselfをキャッチするときは、強いリファレンスリングの出現を避ける
  callback block   ,         self。               。

強引用の例
@interface XYZBlockKeeper : NSObject
@property (copy) void (^block)(void);
@end

@implementation XYZBlockKeeper
- (void)configureBlock {
    self.block = ^{
        [self doSomething];    // capturing a strong reference to self
                               // creates a strong reference cycle
    };
}
...
@end

変更
- (void)configureBlock {
    XYZBlockKeeper * __weak weakSelf = self;
    self.block = ^{
        [weakSelf doSomething];   // capture the weak reference
                                  // to avoid the reference cycle
    };
}

-列挙をブロックで簡略化
例えばNSArrayは以下の方法を定義し,パラメータはblockである.
(void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;

blockには、列挙時の現在のオブジェクト、現在の下付きラベル、および列挙を停止するかどうかを示すブール値の3つのパラメータが表示されます.パラメータとして上記の方法に渡す方法として、(void (^)(id obj, NSUInteger idx, BOOL *stop))のタイプのブロックをカスタマイズすることができます.もちろん、このブロックの内容は列挙するときに配列要素に対してしなければならないことや、列挙が終わるかどうかを決めることなどです.次のようになります.
[array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOL *stop) {
    doSomethingWithObjOrIdx;//do something with obj or idx
     if (...) {
        *stop = YES;
     }
 }];

-同時に実行されるタスクをブロックで簡略化
操作キュー:CocoaとCocoa Touchのタスクリスト.通常、NSOperationオブジェクトを作成して操作を管理し、NSOperationQueueに追加します.NSOperationクラスを継承することによって複雑な操作を書くことができるが、NSBlockOperationを使用して新しい操作を作成することもできる.次のようになります.
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
    ...
}];

この操作をキューに追加します.
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; [mainQueue addOperation:operation];