C'è un modo per determinare se una classe è adatto come una chiave e funzionerà come ci si aspetta, per esempio io voglio usare NSIndexPath come una chiave nella NSDictionary ma non so per certo se due diverse istanze di NSIndexPath con gli stessi valori interi restituiranno sempre lo stesso valore di hash.chiave adatta per NSDictionary
risposta
documento IsEqual di Apple NSObject dice:
se due oggetti sono uguali, essi devono avere lo stesso valore di hash. Questo ultimo punto è particolarmente importante per se si definisce isEqual: in una sottoclasse e si intende inserire istanze di tale sottoclasse in una raccolta. Assicurati che definisca anche hash nella sottoclasse.
Guarda il seguente codice: Risultato
NSIndexPath *indexPath1 = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:0 inSection:0];
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSLog(@"NSIndexPath isEqual's Result: %d", [indexPath1 isEqual:indexPath2]);
NSLog(@"NSObject isEqual's Result: %d", [obj1 isEqual:obj2]);
uscita:
Risultato di NSIndexPath IsEqual: 1
Risultato diNSObject IsEqual: 0
L'implementazione o f NSObject isEqual è che comare l'indirizzo di due oggetti, e l'implementazione hash è l'indirizzo dell'oggetto restituito.
NSIndexPath viene ereditato da NSObject, secondo risultato di uscita NSIndexPath ISEQUAL, attuazione ISEQUAL di NSIndexPath dovrebbe sostituire metodo ISEQUAL superclasse, e NSIndexPath anche sovrascrivere metodo hash superclasse.
In attizione, NSIndexPath è inoltre conforme al protocollo NSCopying.
Quindi NSIndexPath può essere utilizzato come classe Chiave di NSDictionary.
Come un oggetto si comporta come una chiave dipende da come implementa isEqual :. Questo determinerà se due chiavi entrano in collisione.
Ad esempio, i percorsi dell'indice sono uguali - e quindi si scontrano - quando i percorsi hanno lo stesso insieme di indici. Quindi due oggetti distinti che descrivono lo stesso percorso saranno visti dal dizionario come la stessa chiave ... probabilmente come vorresti che fosse.
La mia comprensione è anche il valore dell'hash è importante, immagino che sia una buona ipotesi che NSIndexPath implementa Equal: e l'hash in un modo che si comporterà come ci aspettiamo.Ma è tutto qui, solo una buona ipotesi? Stavo saltando per un protocollo o documentazione che diceva che i metodi è Equal: e l'hash sono sovrascritti invece di dipendere dall'implementazione di NSObjects. –
Un oggetto è uguale se il suo valore hash è uguale al valore hash dell'altro, di solito. Quindi questo rende l'hash molto importante. Per una chiave DEVE avere una classe che produca in modo affidabile lo stesso valore di hash per lo stesso valore dell'oggetto e un valore hash distinto per ogni valore che l'oggetto potrebbe essere. Quindi un modo semplice per confrontare i due valori sarebbe vedere se i loro hash corrispondono :). – borrrden
Secondo la documentazione di Apple per NSDictionary, gli oggetti chiave devono anche essere conformi al protocollo NSCopying, che NSIndexPath fa. – bneely
ci sono tre requisiti per i tasti NSDictionary:
- supporto del protocollo NSCopying
- ragionevole metodo -hash
- IsEqual
NSIndexPath dovrebbe andare bene.
Ma come sai, immagino che NSIndexPath dovrebbe andare bene, ma non lo so per certo. In realtà so solo che NSString è OK perché viene usato così spesso. NSNumber, NSDate, NSURL I ASSUME sono OK, NSValue Non lo so, forse questo è un bug nella documentazione. –
Beh, c'è solo un modo sicuro per scoprirlo - provalo! :-) Se guardi NSIndexPath.h, vedrai che obbedisce al protocollo NSCopying. Puoi anche vedere che ha una variabile di istanza "_hash". E sappiamo che supporta isEqual, quindi per quanto posso dire dovrebbe funzionare bene. Questo è un buon posto per usare un test unitario. E, sì, la documentazione dovrebbe essere migliore. – EricS
- 1. Ottenere la chiave NSDictionary per indice?
- 2. Come ottenere oggetto per chiave da NSDictionary?
- 3. tipo typedef enum come chiave per NSDictionary?
- 4. Utilizzo della classe come chiave in NSDictionary
- 5. Quale classe chiave è adatta per l'ordinamento secondario?
- 6. Utilizzo di int come chiave NSDictionary?
- 7. Maiuscole/minuscole per NSDictionary
- 8. Plist Array per NSDictionary
- 9. inizializzazione NSDictionary
- 10. come ottenere la chiave dal rispettivo valore in un NSDictionary?
- 11. Descrizione di NSDictionary: perché alcuni nomi chiave contengono virgolette?
- 12. Convertire Swift dizionario per NSDictionary
- 13. Aggiunta di NSDictionary ad altro NSDictionary
- 14. NSDictionary setValue:
- 15. NSDictionary writeToFile
- 16. NSDictionary oggetto insensibile al casoForKey:
- 17. Quale metodo per verificare se un NSDictionary contiene una chiave particolare è più veloce?
- 18. Come posso ottenere tutti i valori per chiave specifica da ogni NSDictionary in un NSArray?
- 19. Impossibile trovare una versione adatta per angolare
- 20. come rimuovere l'oggetto da NSDictionary
- 21. instantiating personalizzato classe da NSDictionary
- 22. Tasti NSDictionary ordinati per valore numerico
- 23. NSDictionary ordina per chiavi come float
- 24. Swift - Come ciclo attraverso NSDictionary
- 25. curva di analisi adatta
- 26. UIPickerView con NSDictionary
- 27. JSONKIt serialize NSDIctionary
- 28. convertire NSDictionary a NSString
- 29. NSDictionary + dictionaryWithDictionary o -copy?
- 30. Filtraggio NSArray di oggetti NSDictionary utilizzando NSPredicate
Quindi è necessario verificare se l'implementazione di NSObjects di isEqual: e l'hash sono sovrascritti e assumere sempre lo sarà, il che non è irragionevole. Potrei sollevare un bug contro Apple perché penso che l'override di una classe sia Equal: e l'hash dovrebbe essere documentato. –
Sono d'accordo con te! Il documento di Apple non è abbastanza chiaro in isEqual: e il metodo hash. – xzgyb
@NathanDay: Penso che dovresti sollevare un bug se c'è una classe per cui avrebbe senso avere quei metodi sovrascritti ma non lo sono. – Chuck