2012年1月24日火曜日

ブロックについて(追記)


ブロック変数を宣言し、ブロックリテラルの始まりを表すには、^演算子を使用します。ブロックの本体は、したの例のように、{}で囲まれます

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
ブロックでは、ブロックが定義されているスコープ(有効範囲)に含まれている変数を利用できま す。 ブロックを変数として宣言した場合には、ブロックを関数と同じように使用できます。
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
printf("%d", myBlock(3));
// "21"と出力する


ブロックの概念
アップルのドキュメントにはブロックについて下記のように定義されています


ブロックは、以下のような特徴を持つ無名のインラインコードの集合体です。
● 関数と同様に、型付きの引数リストを持つ
● 推定または宣言された戻り値型を持つ
● ブロックの定義を含むレキシカルスコープの状態を把握できる
● 必要であれば、レキシカルスコープの状態を変更できる
● 変更できるかどうかは、同じレキシカルスコープ内で定義されているほかのブロックと共通である
● レキシカルスコープ(スタックフレーム)が破棄された後も、引き続きそのレキシカルスコープ内で定義されている状態を共有したり変更したりできる
ブロックをコピーしたり、遅延実行のために、ブロックをほかのスレッドに渡すこともできます(または、ブロック自身のスレッド内で、実行ループに渡すことができます)。コンパイラとランタイムは、ブロックのすべてのコピーが存続している間は、そのブロックから参照されるすべての変数を保持するように調整します。ブロックは純粋なCおよびC++で利用できますが、ブロックは常にObjective-Cのオブジェクトでもあります


ブロックの使い方


通常、ブロックは自己完結的な小さなコード部品です。このため、ブロックは、並列に実行されたり、1つのコレクション内の複数のアイテムを対象に実行される一連の作業をカプセル化する手段として、また、別の操作が終了したときのコールバックとして、特に有用です。
ブロックは、主に次の2つの理由から、従来のコールバック関数に代わる有用な手段になります。
1. ブロックを利用すると、メソッド実装のコンテキストで後から実行されるコードを、呼び出しの時点で記述できます。したがって、通常、ブロックはフレームワークメソッドのパラメータになります。

2. ブロックでは、ローカル変数にアクセスできます。
操作の実行に必要なすべてのコンテキスト情報を具体化したデータ構造を要求するコールバックを使用する代わりに、単純にローカル変数に直接アクセスできます。

変数について
ブロック内で使える変数は
クラス変数、ブロックで定義されている関数の変数、__blockストレージ型で定義された変数の3つです。
ブロック内に新しい変数を定義してもエラーが出ます。

__blockストレージ型の使い方例
__block int x = 123; //  xはブロック外
void (^printXAndY)(int) = ^(int y) { //yしか変数が定義されていない
x = x + y;
printf("%d %d\n", x, y);
};
printXAndY(456); // "579,456"と出力する
// xは現在579

No response to “ブロックについて(追記)”

Leave a Reply