ログイン



Block構文(クロージャー)

日曜日, 8月 25th, 2013 by

Block構文は、iOS4.0で導入された構文。関数をオブジェクトとして扱うことができる。Block内にstaticな変数を使うと、内部状態を持つBlockを作ることができる。Block内からBlock外の変数を参照することはできるが、変更はできない。Block外の変数を変更するには、ブロック外の変数の宣言に__blockを指定する必要がある。

カウンター

    int (^counter)() = ^(){
        static int i = 1;
        return i++;
    };
   
    NSLog(@"%d", counter());//1
    NSLog(@"%d", counter());//2
    NSLog(@"%d", counter());//3
//引数が無い場合は、()を省略できる。
    int (^counter2)() = ^{
        static int i = 1;
        return i++;
    };

数値の合計を計算

    int (^sum)(int) = ^(int num){
        static int value = 0;
        value += num;
        return value;
    };
    NSLog(@"%d", sum(3));//3
    NSLog(@"%d", sum(5));//8
    NSLog(@"%d", sum(10));//18

文字列を連結

    NSString * (^appender)(NSString *) = ^(NSString * str){
        static NSString *_str = @"";
        _str = [_str stringByAppendingString:str];
        return _str;
    };
   
    NSLog(@"%@", appender(@"test"));//test
    NSLog(@"%@", appender(@"test"));//testtest
    NSLog(@"%@", appender(@"test"));//testtesttest

外部の変数も参照できる。変数はクロージャ生成時に複製されるため、もとの変数の値が変わっても影響されない。

    int i = 3;
    int (^add3)(int) = ^(int num){
        return i + num;
    };
   
    NSLog(@"%d", add3(5));//8
   
    i = 4;
   
    NSLog(@"%d", add3(5));//8

通常、外部の変数は変更できない。__block指定子が付いている変数はBlockの中から変更できる。

    int j = 1;
    __block int k = 1;
    void (^inc)() = ^() {
        j = 2;//エラーになりコンパイルできない
        k = 2;//問題なく実行できる。
    };
    inc();