「第5章 マルチスレッド」にて、ちょっとAdvanced過ぎるかも、と思った内容を補遺として連載してっちゃいますよ。
というわけで今回は、本当に187ページで説明している「__block修飾子」について、もうちょっと掘り下げてみます。
たとえば、「__block修飾子」を付けたint型のauto変数を用意してみましょう。
int main()
{
__block int total = 11;
++total;
return total;
}
「__block」付いてる以外は、ごく普通のコードです。
しかし、コレ実際何がどうなるんでしょうか。
実は、clangを使うと一瞬でわかります。
$ clang -rewrite-objc test.m
これでObjective-Cのソースコードを、おなじみのC++のソースコードに変換することが可能なのです。
あ、C++になじみがない方もご安心を。--rewrite-objcで生成されるC++ソースコードは、ほぼC言語です(ほぼC言語なのにC++として生成されるのか、それは謎です)。
生成されたC++ソースコードを見てみると。
(抜粋)
#define __block
struct __Block_byref_total_0 {
void *__isa;
__Block_byref_total_0 *__forwarding;
int __flags;
int __size;
int total;
};
int main()
{
__block struct __Block_byref_total_0 total = {
(void*)0,
(struct __Block_byref_total_0 *)&total,
0,
sizeof(struct __Block_byref_total_0),
11
};
++(total.__forwarding->total);
return (total.__forwarding->total);
}
int型だったtotalが、なにやら複雑な構造体になっていることがわかります。そして元々のint totalは、構造体のメンバーとして収納されています。
なぜこのような構造体が必要なのか。それはiOS 4プログラミングブック 189ページで説明しているように、Block_copyによって__block変数がstackからheapに移動されてもへいちゃら! と言えるようになっているわけです。
以上、何気なく付けた__block修飾子が実はこんな構造体になってました、というお話でした。
その2に続きます。