2011-12-22 3 views
1

ハッシュのような構造でキーとしてカスタムオブジェクトを使用したいと思います。私はNS[Mutable]Dictionaryを使ってみましたが、私のオブジェクトがキーになるためには、NSCopyingプロトコルを実装しなければなりません。 NSDictionaryは、私が読んだ限り、すべての鍵にcopyというメッセージを送信しています。私はプロトコル(私のオブジェクトはかなり複雑です)を実装したくないし、コピーしたくない。私の選択肢は何ですか?私は何か持っていますか?Objective-Cでオブジェクトをキーとして使用する方法

+1

明らかな代替方法は、カスタムオブジェクトをキーとして使用しないことです。一意に識別するために使用できる文字列や数字はありませんか? – Thilo

+0

私は無用なコピーなしでオブジェクトをキーとしてオブジェクトを使用できるようにする代替手段を求めていました。 –

答えて

3

NSDictionaryはフリーダイヤルでCFDictionaryRefでブリッジされていますが、実際にはオブジェクトを追加するときの動作が異なります。具体的には、NSDictionary-setObject:forKey:は、キーをコピーしますが、CFDictionaryRefCFDictionarySetValue()は、キーをコピーしません。つまり、コピーできないキーを使用する場合は、代わりにCFDictionarySetValue()を使用して辞書に追加することができます。

CFDictionarySetValue((CFMutableDictionaryRef)myDict, myKey, myValue); 

これでもキーは保持されますが、コピーされません。そして、あなたは他のすべてのために通常のNSDictionaryメソッドを使用することができます。

+0

あなたは厄介なことがあり、 'copy'は' [self retain] 'を返しますが、それは明らかにセマンティクスを壊します。 – Wevah

+0

これは私が探していたものです、私は私のオブジェクトを保持することに対して何も持っていません、それは理にかなっていますが、コピーは少しです。私はなぜNSDictionaryバージョンでキーをコピーするのを選択したのだろうかと思います... –

+1

@ValentinRadu - キーをコピーします。それ以外の理由でキーをコピーすると、後でキーを変更すると辞書が壊れてしまいます。コピーが含まれていないスキームを使用する場合は、キーオブジェクトがディクショナリにある間にハッシュされたフィールドを決して変更しないでください。 –

1

は、オブジェクトを保持するNSDictionaryが必要ですか?そうでない場合、あなたはNSValueにそれを回すとキーとしてそれを使用することができます

NSValue *value = [NSValue valueWithNonretainedObject:yourCustomObject]; 
[dictionary setObject:someObject forKey:value]; 

これは少し厄介しかしNSCopyingを実装する代わりにしていることができます。

+0

辞書がオブジェクトへの唯一の参照であれば、それは死にます。 –

+0

うん、私は明らかだったと思った。 'CFDictionary'は良い解決策です。 – XJones

0

あなたはこれを行うことができます:

- (id)copyWithZone:(NSZone *)zone { 
    return [self retain]; 
} 
+0

オブジェクトが不変でない限り、それはむしろ悪い考えです。 –

+0

'hash'と' isEqual: 'メッセージに関しては不変でなければなりません。デフォルトでは、それらは単にオブジェクトポインタを使用します。 –

+1

何を意味するのですか?実際にコピーをスキップする '-copy'メソッドを公開することは、*本当に悪い考えです*。 'Klass newobj = [obj copy];のようなコードを意味します。 [newobj mutateSomeProperty]; 'は、元の' obj'を実際に修正します。これは、 '-copy'が何を意味しているかのすべての期待に反するものです。 –

1

独自の辞書をロールバックすることができます。それほど難しいことではありません。

別のオプションは、 "the"オブジェクトへのポインタを含む代理オブジェクトを使用することです。サロゲートはハッシュを実装し、isEqualの比較対象のフィールドをコピーまたは参照します。比較フィールドが参照されても変更されていないことを保証するために、基本的なサニティチェックを行うことができます。

+0

既存のディクショナリを使用するよりも難しい、つまり「CFDictionary」。 – dreamlax