Kakao ist NSDictionary: warum sind keys kopiert?
Alle Objekte als Schlüssel verwendet, die in NS(Mutable)Wörterbücher unterstützen muss, die NSCopying Protokoll, und diese Objekte werden kopiert, wenn Sie gewohnt sind, im Wörterbuch.
Ich Häufig verwenden möchten, schwerere Gegenstände wie Schlüssel, einfach zu Karte einem Objekt zum anderen. Was ich wirklich meine, wenn ich das Tue, ist effektiv:
[dictionary setObject:someObject forKey:[NSValue valueWithPointer:keyObject]];
("Wenn ich zurückkomme, und die hand, die Sie die gleiche Taste Objekt-Instanz wieder, hol mir den gleichen Wert heraus.")
...das ist genau das, was ich am Ende tun, um dieses design manchmal. (Ja, ich weiß, über NSMapTable in desktop-Kakao, aber z.B. iPhone dies nicht unterstützt.)
Aber was ich nicht wirklich bekommen, ist, warum das kopieren des Schlüssels ist notwendig oder wünschenswert in den ersten Platz. Was hat es zu kaufen, die Umsetzung oder die Anrufer?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Kopie wird sichergestellt, dass die Werte, die als Schlüssel verwendet nicht ändern "hinterhältige", während Sie als Schlüssel verwendet. Betrachten Sie das Beispiel von einem mutable-string:
Lassen Sie uns davon ausgehen, dass das Wörterbuch nicht kopieren Sie die Schlüssel, sondern nur einen
retain
ed es. Wenn jetzt, zu einem späteren Zeitpunkt, wird der ursprüngliche string wird modifiziert, dann ist es sehr wahrscheinlich, dass Sie nicht gehen, um herauszufinden, Ihre gespeicherten Wert in das dictionary wieder, selbst wenn Sie den gleichen Schlüssel-Objekt (d.h., die einekey
Punkte in dem obigen Beispiel).In, um sich zu schützen gegen einen solchen Fehler, das Wörterbuch kopiert alle Schlüssel.
Beachten Sie, durch die Art und Weise, dass es einfach genug, um zu definieren
-copyWithZone:
als nur tunreturn [self retain]
. Dies ist erlaubt und guten code wenn Ihr Objekt ist unveränderlich, und dieNSCopying
Vertrag ist speziell so konzipiert, dass das Objekt zurückgegeben werden (sorta, kinda) unveränderlich:(aus NSCopying Referenz)
und
(aus -copyWithZone: Referenz)
Selbst wenn Ihre Objekte sind nicht unveränderlich, Sie kann Weg mit, dass die Umsetzung, wenn Sie immer nur die Identitäts-basierte Gleichheit/hash-Implementierungen, d.h., Implementierungen, die nicht betroffen sind, in irgendeiner Weise von dem Objekt den internen Zustand.
keyObject
beibehalten werden, dass code, der wird es nicht tun, da es behandeltkeyObject
als Zeiger auf etwas, das nicht unbedingt ein Objekt, so hat es keine Möglichkeit zu wissen, dass es könnte es behalten. Ich bin mir nicht sicher, dassvalue:withObjCType:
würde behalten, auch wenn übergeben@encode(id)
. Um absolut sicher sein, es bewahren Sie Ihre Schlüssel, dann müssen Sie entweder verwenden NSMapTable (Sie implizieren, dass Sie können nicht dies tun, weil Sie die Entwicklung für das iPhone), verwenden Sie CFDictionary statt NSDictionary (überall verwenden Sie die dict, nicht nur in seiner Schöpfung), oder machen Sie Ihre eigenen NSValue Unterklasse.id
s. Aber das code riecht schlecht genug, um zu wissen, dass Sie tun etwas gefährlich...Wenn Sie möchten, speichern Zeiger als Schlüssel, dann müssen Sie wickeln Sie Sie in ein
NSValue
Objekt mit+valueWithPointer:
.+valueWithNonretainedObject:
statt.Seit iOS 6 wenn Sie möchten, verwenden Sie Zeiger als Schlüssel, die Sie verwenden können, die
NSMapTable
Objekt finden Sie unter http://nshipster.com/nshashtable-and-nsmaptable/Können Sie angeben, ob Schlüssel und/oder Werte sind dringend oder schwach gehalten:
Eine weitere option, die angebracht sein könnte, manchmal ist die Verwendung
NSCache
, die hält, Tasten stark und ist eigentlich thread-safe.