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
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 (^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
static int value = 0;
value += num;
return value;
};
NSLog(@"%d", sum(3));//3
NSLog(@"%d", sum(5));//8
NSLog(@"%d", sum(10));//18
文字列を連結
外部の変数も参照できる。変数はクロージャ生成時に複製されるため、もとの変数の値が変わっても影響されない。
int i = 3;
int (^add3)(int) = ^(int num){
return i + num;
};
NSLog(@"%d", add3(5));//8
i = 4;
NSLog(@"%d", add3(5));//8
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();
__block int k = 1;
void (^inc)() = ^() {
j = 2;//エラーになりコンパイルできない
k = 2;//問題なく実行できる。
};
inc();