Skip to content
Keita Mitsuhashi edited this page May 4, 2015 · 4 revisions

BlockとGCD

そもそもこれはなにか

マルチスレッドを実現する為の手法.BlockはC, C++, Objective-Cに提供されている.
現在の計算機のアーキテクチャではマルチスレッドを提供することが常識である.
このあたりの話(マルチスレッドとはなにか,なぜ必要なのか,どのように実現されるのか)を詳しく知りたい場合は,
コンピュータの構成と設計, パターソン&ヘネシー
に詳しい.
さらに詳しく知りたい場合は,
コンピュータアーキテクチャ 定量的アプローチ
もしくは
オペレーティングシステムの概念
がおそらくこの世で一番詳しい.

要は並列処理をするためにObjective-Cに提供されている仕組みが,BlocksとGCDの合わせ技ってこと.

Blocksについて

C, C++, Objective-Cに対してクロージャを提供する仕組み.

クロージャってなに?

説明するのが非常に難しい概念(らしい).
ひとまず,大事な要素だけ列挙してみる

  • クロージャ = 関数
  • クロージャはある関数の中で定義される,別の関数
  • クロージャは元の関数の変数を参照できる

たとえば,いま,関数 outer( ) を考えてみる.上述によると,この中に別の関数 innner( ) をぶち込んでしまえばいいらしい.
このとき,inner( )を,outer( )で宣言されている変数を参照させるようにしたらそれがクロージャだ!

function outer()
{
	var x = 1

	function (){
		alert(x);
	}

}

この結果は以下.

1

そして最大の特徴

値を保持する!

これがクロージャの存在する理由っすね.たとえば,

function outer()
{
	var x = 1;

	function f(){
		x = x + 1;
		alert(x);
	}

	return f();
}

var f = outer();	// 関数型の変数
f(); // 1
f(); // 2
f(); // 3

すると結果は

123

となる.これはどういう事か?

クロージャで定義された関数,オブジェクトっぽく使えね?

ってことです!最近苦心してるハードウェア設計論的に言うと,レジスタ型変数しかも関数ver. って感じでしょうか

そしてBlockとは?

クロージャが分かったところでBlockとは結局,

  • 他の関数の中でインラインに定義され,元の関数の変数を参照でき,オブジェクトっぽく使えるクロージャを実現する為の 書き方

つまりただの文法っすね.形としては以下

^{
	// ここにブロックの実装を書く.
}

先述のようにクロージャは関数型の変数だから,返り値も引数も取れるし,変数っぽく宣言する事も出来る.

void (^someBlock)() = ^{
	// ここがブロックの実装
}

これは,void型で引数なしのsomeBlockという名前の変数を定義している.

まとめると,

返り値の種類 (^ブロックの名前)(引数) = ^{};

という形で宣言される.

実装するときに注意する点

Blockは変数であるから,プロパティメソッドの引数になったりもする.サンプルコード読んだりするときには,なぜblockで実装されているのかとか考えると良いと思うし,逆に分かってないとすごく読みにくい.

mixi trainingの方にも書いてあるけど,実際に実装するときにはコードが長くなったり煩雑になったりしがちなのでtypedefを使うのがベター

GCDによる並列処理

先述のように計算機では並列処理なしではなにもやっていけない(もしなかったらマウスが動いている間にあらゆる処理が止まる事になっちゃう).
mixi trainingにもあるように並列処理の実現方法は複数あるのだけど,スレッドを立てて処理をさせるっていうのは,素朴でハードウェアに近い方法なので分かりやすいものの,アプリケーション側からハードウェアの処理とかをいちいち命令してあげなきゃいけないのでめんどくさい!で,実装されたのが,並列処理を抽象化したクラスGCD.

このとき,並列処理で行ってほしい処理をblockとしてキューに渡すっていう話です!

あとは教科書どおりかな