Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

橋向かいのsetObject:forKey:

タグ: Objective-C

NSDictionaryのtoll-free bridgeについてコメントしていて、ふと浮かんだ疑問。
NSMutableDictionaryのsetObject:forKey:は「キーをコピーして」格納する。
CFMutableDictionaryのCFDictionarySetValueは「キーをCFDictionaryRetainCallBackに掛けて」格納する。
では、NSMutableDictionary *をtoll-free bridgeでCFMutableDictionaryRefに型変換してCFDictionarySetValueした場合、はたしてキーはコピーされるか否か。

「setObject:forKey:が自分でキーをコピーしてCFDictionarySetValueに渡す」ような流れになっているのであれば、コピーはされないはず。
しかし「CFDictionaryRetainCallBackがキーをコピーする」ようになっているとしたら、コピーされることになる。

@interface Hoge : NSObject<NSCopying>
{
    NSInteger value;
}
- (void)log;
@property NSInteger value;
@end

@implementation Hoge
@synthesize value;
- (id)copyWithZone:(NSZone *)zone
{
    Hoge *hoge = [[Hoge allocWithZone:zone] init];
    hoge.value = self.value;
    return hoge;
}
- (void)log
{
    NSLog(@"%d: %p (retainCount: %d)", self.value, self, [self retainCount]);
}
Hoge *hoge1 = [[[Hoge alloc] init] autorelease];
hoge1.value = 1;
[hoge1 log];

Hoge *hoge2 = [[[Hoge alloc] init] autorelease];
hoge2.value = 2;
[hoge2 log];

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:hoge1 forKey:hoge1];
CFDictionarySetValue((CFMutableDictionaryRef)dict, hoge2, hoge2);
for(Hoge* hoge in [dict keyEnumerator])
{
    [hoge log];
}

MacOS X 10.5.6での結果。

1: 0x103a20 (retainCount: 1)
2: 0x1052b0 (retainCount: 1)
1: 0x106160 (retainCount: 1)
2: 0x1052b0 (retainCount: 3)

CFDictionarySetValueで追加した方(2:)はアドレスが変わっていない(=コピーしていない)。
参照数も順当な値(「hoge2」「キー」「値」の計「3」)を示している。
つまりこの方法を使えば、「NSCopyingプロトコルに準拠しないオブジェクト」をNSDictionaryのキーにすることも一応可能というわけだ。
よく考えたら、「CFMutableDictionaryRefをNSMutableDictionary *に変換してsetObject:forKey:する場合もキーはコピーされなければならない」のだから、CFDictionaryRetainCallBackではなく、setObject:forKey:がキーをコピーするのは当然と言える。

スポンサーサイト

コメント

[C26]

難しいですが、大体理解できたと思います。Cocoa/Core Foundation/Objective-Cこの辺の生い立ちから良く分かっていない状態なので、なかなか思うように勉強が進みませんが、疑問に思った事は自分で確かめつつ勉強を進めていきたいと思います。どうもありがとう御座いました。
  • 2009-04-26 02:06
  • ken
  • URL
  • 編集

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/194-6be45455
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。