tl;dr:
CFDictionaryRef
提供されたデフォルトのコールバック関数を使用して を作成します。それはあなたが望むことをします。とは呼ばないでくださいNSDictionary
。
はい、CFDictionaryRef
キーを保持し、コピーしない を作成できます。実際、これは のデフォルトの動作ですCFDictionaryRef
。
のドキュメントにCFDictionaryCreateMutable()
は次のように書かれています:
ディクショナリに CFType オブジェクトのみが含まれる場合は、ポインタをkCFTypeDictionaryKeyCallBacks
このパラメータとして渡し、デフォルトのコールバック関数を使用します。
(したがって、通常のObjective-Cオブジェクトのみを配列に入れ、void *
ポインターなどのランダムなものを入れない場合、これが必要です)
そして、ドキュメントにkCFTypeDictionaryKeyCallBacks
は次のように書かれています:
CFDictionaryKeyCallBacks
CFDictionary のキーがすべて CFType 派生オブジェクトである場合に使用するのに適した一連のコールバックを含む定義済みの構造体。保持コールバックはCFRetain
、解放コールバックはCFRelease
、コピー コールバックはCFCopyDescription
、等価コールバックはCFEqual
です。したがって、ディクショナリの作成時にこの定数へのポインタを使用すると、キーはコレクションに追加されると自動的に保持され、コレクションから削除されると解放されます。
retain
コールバックは(実際には存在しない)CFRetain()
のようなものではないことに注意してください。CFCopyObject
実際、Core Foundation には「任意のオブジェクトをコピーする」標準的な方法がありません。そのためCFStringCreateCopy
、CFArrayCreateCopy
、CGPathCreateCopy
、 などの関数が存在します。
したがって、できることは、次のように辞書を作成することです。
CFDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
これで、キーを保持し、コピーしないディクショナリが作成されました。
私が言おうとしていることを理解していただけるように、次の部分を大きな文字で書きます。
あなたが作成したこの辞書はNSDictionary
.
はい、無料NSDictionary
でCFDictionaryRef
ブリッジされています。ただし、これCFDictionaryRef
を にキャストすると、ドキュメントの次NSDictionary
の行のため、そのブリッジングの悪用になります。NSDictionary
...キーは任意のオブジェクトにすることができます(NSCopying
プロトコルに準拠している場合-以下を参照)
同様に、ドキュメントには-[NSMutableDictionary setObject:forKey:]
明示的に次のように記載されています。
キーがコピーされます ( を使用しcopyWithZone:
ます。キーは NSCopying プロトコルに準拠している必要があります)。
ディクショナリのキーは に準拠する必要<NSCopying>
はなく、 を使用してコピーされません。-copyWithZone:
つまり、ディクショナリはNSDictionary
(またはNSMutableDictionary
) ではありません。コードで使用されている場合NSDictionary
は常に、キーがコピーされる(保持されない) キーと値のマップを提供する必要があります。それが API コントラクトです。それ以外のことを行うと、未定義の動作が発生する可能性があります。
(一部のオブジェクトが にオーバーライド-copy
するという事実return [self retain]
は実装の詳細であり、「 とは何か」に関するこの説明には関係ありませんNSDictionary
。)