2012-07-01 14 views
48

Sicher ist ein geordneter Satz ein spezifischerer Fall eines Satzes, warum erbt NSOrderedSet von NSObject statt ?Warum erbt NSOrderedSet nicht von NSSet?

+0

Wenn developer.apple.com im Moment nicht down wäre, würde ich mir die Dokumentation ansehen, denn jetzt hast du mich neugierig gemacht! Ausgezeichnete Frage. Und hoffentlich bleibt eine Apple-Seite nicht zu lange stehen, oder? – WendiKidd

+2

(Disclaimer: Das ist pure Spekulation, und zu wenig überzeugend für mich, um es tatsächlich als Antwort zur Verfügung zu stellen, aber ...) Ein 'NSOrderedSet' ist ein spezifischerer Fall von sowohl einem' NSSet' als auch einem 'NSArray' . Das sind Klassen, keine Protokolle, und in Objective-C gibt es keine Mehrfachvererbung. Also, was wählst du? Es gibt ein Argument für 'NSSet' wegen des Namens, aber es könnte total' NSUniqueArray' gewesen sein, oder? Gehen Sie auf Nummer sicher, lassen Sie beide fallen ... –

+1

Ich sehe genau, was Sie sagen, aber Sie haben Recht, dass es nicht so überzeugend ist. Ich würde intuitiv erwarten, dass '[aSet intersectsSet: anOrderedSet]' möglich ist (aber nicht, da 'NSOrderedSet' keine Unterklasse von' NSSet' ist), so dass 'NSSet' für eine Oberklasse eine logischere Wahl ist als' NSArray "- und selbst wenn sie gleich logische Entscheidungen treffen, macht das Verlieren des Polymorphismus die Wahl sowieso zu einer minderwertigen Option. – jhabbott

Antwort

72

Ich ging durch die Schnittstelle von NSSet und Sie haben Recht, geordnete Sätze scheinen die Liskov substitution principle zu erfüllen und könnte daher von erben.

Es gibt eine kleine Methode, die das bricht: mutableCopy. Der Rückgabewert von mutableCopy muss ein NSMutableSet sein, aber NSMutableOrderedSet sollte von NSOrderedSet erben. Du kannst nicht beides haben.

Lassen Sie mich mit etwas Code erklären. Zuerst schauen wir uns auf das richtige Verhalten von NSSet und NSMutableSet:

NSSet* immutable = [NSSet set]; 
NSMutableSet* mutable = [immutable mutableCopy]; 

[mutable isKindOfClass:[NSSet class]]; // YES 
[mutable isKindOfClass:[NSMutableSet class]]; // YES 

Nun lassen Sie uns NSOrderedSet erbt von NSSet vorgeben und NSMutableOrderedSet erbt von NSOrderedSet:

//Example 1 
NSOrderedSet* immutable = [NSOrderedSet orderedSet]; 
NSMutableOrderedSet* mutable = [immutable mutableCopy]; 

[mutable isKindOfClass:[NSSet class]]; // YES 
[mutable isKindOfClass:[NSMutableSet class]]; // NO (this is the problem) 

Was passiert, wenn NSMutableOrderedSet von NSMutableSet statt geerbt? Dann bekommen wir ein anderes Problem:

//Example 2 
NSOrderedSet* immutable = [NSOrderedSet orderedSet]; 
NSMutableOrderedSet* mutable = [immutable mutableCopy]; 

[mutable isKindOfClass:[NSSet class]]; // YES 
[mutable isKindOfClass:[NSMutableSet class]]; // YES 
[mutable isKindOfClass:[NSOrderedSet class]]; // NO (this is a problem) 

In Beispiel 1, würden Sie nicht in der Lage sein, ein NSOrderedSet in eine Funktion zu übergeben ein NSSet erwarten, weil das Verhalten unterschiedlich ist. Grundsätzlich handelt es sich um ein Abwärtskompatibilitätsproblem.

In Beispiel 2 können Sie keine NSMutableOrderedSet in eine Funktion übergeben, die eine NSOrderedSet erwartet, weil ersteres nicht von letzterem erbt.

All dies ist, weil NSMutableOrderedSet nicht von NSMutableSet und NSOrderedSet erben kann, weil Objective-C nicht mehrfache Vererbung hat. Der Weg, um dies zu umgehen ist, Protokolle für NSMutableSet und NSOrderedSet zu machen, weil dann NSMutableOrderedSet beide Protokolle implementieren kann. Ich schätze die Apple-Entwickler, obwohl es ohne die zusätzlichen Protokolle einfacher war.

+0

Ich denke, die Protokolle würden mehr Sinn machen - es könnte mehr damit zu tun haben, dass das 'NSMutableSet' bereits definiert war und noch kein Protokoll für die Veränderlichkeit verwendet hat.Konnte das Protokoll nicht hinzugefügt werden, obwohl "NSMutableSet" bereits damit konform ist? – jhabbott

+0

Wenn sie wollten, könnten sie ein neues Protokoll hinzufügen, ohne etwas zu brechen. Wir könnten es in Zukunft hinzugefügt sehen. –

+2

Große Antwort, das wurde in NSHipster Buch verwendet, das ist, wie ich diese Frage fand ... wissen Sie, warum das NSHipster Buch dieses Problem direkt mit NSSet als ein Klassencluster verbindet ?, Ich sehe einfach nicht, wie wenn NSSet war eine konkrete Klasse, dass dies mit dem Problem der veränderbaren Kopie anders wäre, weißt du? http://shipster.com/nsorderedset/ –