2011-03-03

『iOS 4プログラミングブック』 第5章マルチスレッド 補遺 その7



そろそろ浸透して話題にも上がらなくなってきた(?)『iOS 4プログラミングブック』。

補遺その7では、BlocksのObjective-C支援機能に切り込んでみます。

191ページに書いてあるとおり、Objective-Cのオブジェクトは、Block_copy時に自動的にretainされます。


NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSString *string = [NSString stringWithFormat:@"score = %d", score];

void (^block)() = Block_copy(^{

NSLog(@"%@", string);

});

[pool drain];

/* stringはblockからretainされてるから、まだ生きてる */



これどういう仕組みなんでしょう?


Objective-Cのオブジェクトは、みなNSObjectの子供。

NSObjectは、C言語としては、__attribute__((NSObject))アトリビュートの付いた変数。


てことで、Block_copy時に__attribute__((NSObject))のついた変数をretainして、Block_release時にreleaseするコードを、コンパイラは簡単に生成できるわけですね。


http://clang.llvm.org/docs/Block-ABI-Apple.txt
2.2.1 Importing __attribute__((NSObject)) variables.



しかし、この自動retainする機能。便利なのはいいのですが、実は気づかないうちに、循環参照してdeallocされない状況に陥ることもある諸刃の剣。

Blockが、Blockをretainしているクラスのselfを自動retainしちゃう、という落とし穴。

詳しくは『iOS 4プログラミングブック』の193ページに!