Core Foundation

Cocoaプログラミングは、Objective-Cという言語とCocoaというフレームワークを用いて行われるのだが、このObj-Cという言語はオブジェクト以外そのままC言語である。CocoaとCarbonって全然違うもの、と思っている人もいるかもしれないが、CocoaからCarbonの機能を呼び出すことは普通に出来ることである。
さて、CocoaとCarbonの「下」にはCore Foundationというものがある。両方を支える基礎みたいなものである。このCore Foundationはまた、「Cで書かれたオブジェクト指向フレームワーク」である*1


さて、Core FoundationにはCocoaに対応したオブジェクトがある。CFStringとか、CFArrayとか、そういう基本的なものである。そしてこれは「Toll-free bridge」でCocoaのオブジェクトとして扱える。いやあ、これ最初知ったときは驚いたんですよ。
多分内部的には同じものだったりするんだろう。

*1:詳しくはHMDTをご覧になるとよいかもしれない。

retain/releaseのないNSMutableDictionary

で、Core FoundationのオブジェクトをCocoaで使うってことに何の利点があるかっていうと、いろいろオブジェクトの挙動を深くいじれたりする。
コレクションクラス、NSArrayやNSDictionaryやそのmutableサブクラスは、オブジェクトを登録するとretainメッセージを送って保持する。で、取り除くとreleaseメッセージを送って開放する。これはCocoaのメモリ管理の基本だ。
しかしこの挙動が仇になるときもある。retain/releaseのないNSMutableArrayやNSMutableDictionaryが欲しくなるときがあるのだ*1
そんなときこうする。

CFDictionaryValueCallBacks dictionaryValueCallBacks = kCFTypeDictionaryValueCallBacks;
dictionaryValueCallBacks.retain = NULL;
dictionaryValueCallBacks.release = NULL;

return (NSMutableDictionary *)CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&dictionaryValueCallBacks);

CFMutableDictionaryを作成するときには、「キーに対するコールバック」「バリューに対するコールバック」を指定することが出来る。すなわち、retainやreleaseや、Dictionaryならhashとかそういう関数のポインタのセットだ。対応する部分をNULLにすると、もうその関数は呼ばれなくなる。
そしてこれをNSMutableDictionaryとして返すことが出来る。こうすれば、このコード以外からは出来たものは完全なNSMutableDictionaryのインスタンスに見える。ただし、retain/releaseがされないことを除いて。
便利です。

*1:実はThousandのスレッドや板やお気に入りやの管理がそれ