Sicuramente un insieme ordinato è un caso più specifico di un insieme, quindi perché fa NSOrderedSet
ereditare da NSObject
piuttosto che NSSet
?Perché NSOrderedSet non eredita da NSSet?
risposta
Sono passato attraverso l'interfaccia di NSSet
e hai ragione, i set ordinati sembrano soddisfare Liskov substitution principle e potrebbero quindi ereditare da NSSet
.
C'è un po 'di metodo che rompe questo: mutableCopy
. Il valore di ritorno di mutableCopy
deve essere un NSMutableSet
, ma NSMutableOrderedSet
dovrebbe ereditare da NSOrderedSet
. Non puoi avere entrambi.
Lasciami spiegare con un po 'di codice. In primo luogo, diamo un'occhiata a un corretto comportamento delle NSSet
e NSMutableSet
:
NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];
[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
Ora, facciamo finta NSOrderedSet
eredita da NSSet
, e NSMutableOrderedSet
eredita da 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)
E se NSMutableOrderedSet
ereditato da NSMutableSet
invece? Poi abbiamo un problema diverso:
//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)
Nell'esempio 1, non sarebbe in grado di passare un NSOrderedSet
in una funzione che si aspetta un NSSet
perché il comportamento è diverso. Fondamentalmente, si tratta di un problema di compatibilità con le versioni precedenti.
Nell'esempio 2, non è possibile passare un NSMutableOrderedSet
in una funzione che si aspetta un NSOrderedSet
poiché il primo non eredita da quest'ultimo.
Tutto questo perché NSMutableOrderedSet
non può ereditare da entrambi NSMutableSet
e NSOrderedSet
perché Objective-C non ha ereditarietà multipla. Il modo per aggirare questo è quello di creare protocolli per NSMutableSet
e NSOrderedSet
, perché quindi NSMutableOrderedSet
può implementare entrambi i protocolli. Immagino che gli sviluppatori Apple fossero più semplici senza i protocolli aggiuntivi.
Penso che i protocolli avrebbero più senso - potrebbe essere più a che fare con il fatto che il 'NSMutableSet' era già definito e non utilizzava già un protocollo per la mutabilità.Il protocollo non può ancora essere aggiunto nonostante il fatto che 'NSMutableSet' sia già conforme ad esso? – jhabbott
Se lo volessero, potrebbero aggiungere un nuovo protocollo senza rompere nulla. Potremmo vederlo aggiunto in futuro. –
Ottima risposta, questo è stato usato nel libro NSHipster, che è il modo in cui ho trovato questa domanda ... sai perché il libro NSHipster collega questo problema direttamente a NSSet essendo un cluster di classe ?, Semplicemente non vedo come se NSSet fosse una classe concreta che questo sarebbe diverso con il problema della copia mutevole, lo sai? http://nshipster.com/nsorderedset/ –
Se developer.apple.com non fosse verso il basso in questo momento, mi piacerebbe andare a dare un'occhiata ai documenti, perché ora hai me curioso! Ottima domanda E speriamo che un sito Apple non rimanga per troppo tempo, giusto? – WendiKidd
(Disclaimer: Questa è pura speculazione, e troppo poco convincente per me volerlo fornire effettivamente come risposta, ma ...) Un 'NSOrderedSet' è un caso più specifico sia di un' NSSet' che di un 'NSArray' . Quelle sono entrambe classi non protocolli e non c'è eredità multipla in Objective-C. Quindi, quale scegli? C'è un argomento per 'NSSet' a causa del nome, ma potrebbe essere stato completamente 'NSUniqueArray', giusto? Gioca sul sicuro, buttale entrambi ... –
Vedo esattamente quello che stai dicendo, ma hai ragione che non è poi così convincente. Prevedo intuitivamente che '[aSet intersectsSet: anOrderedSet]' sia possibile (ma non lo è dato che 'NSOrderedSet' non è una sottoclasse di' NSSet'), quindi 'NSSet' rappresenta una scelta molto più logica per una superclasse di' NSArray' - e anche se hanno fatto scelte ugualmente logiche, perdere il polimorfismo rende comunque la scelta di nessuna opzione inferiore. – jhabbott