Qual è il NSObject IsEqual: e funzione di hash di default?
-
12-09-2019 - |
Domanda
Ho una classe modello di database che è un NSObject
. Ho una serie di questi oggetti in un NSMutableArray
. Io uso indexOfObject:
per trovare una corrispondenza. Il problema è che cambia l'indirizzo di memoria dell'oggetto modello. Così sto override del metodo hash
per restituire del modello ID fila. Questo però non risolvere il problema. Devo anche l'override del metodo isEqual:
per confrontare il valore del metodo hash
.
Che cosa significa l'uso metodo di isEqual:
per determinare l'uguaglianza di default?
Sto assumendo che utilizza l'indirizzo di memoria. Dopo aver letto il documentazione isEqual:
ho pensato che utilizzato il valore dal metodo hash
. Ovviamente, questo non è il caso come il mio tentativo di ignorare tale valore non ha risolto il mio problema iniziale.
Soluzione
Come avete indovinato, il comportamento di default di NSObject
isEqual:
è confrontare l'indirizzo di memoria dell'oggetto. Stranamente, questo non è attualmente documentato nel NSObject Class Reference , ma è documentato nella Introspezione documentazione, in cui si afferma:
L'implementazione predefinita
NSObject
diisEqual:
controlla semplicemente per l'uguaglianza puntatore.
Naturalmente, come si è certamente a conoscenza, sottoclassi di NSObject
possono ignorare isEqual:
a comportarsi in modo diverso. Ad esempio, il metodo di NSString
isEqual:
, quando passò un'altra NSString
, per prima cosa controllare l'indirizzo e poi verificare la presenza di una corrispondenza letterale esatta tra le corde.
Altri suggerimenti
La risposta circa implementazione predefinita di isEqual:
è uno completo. Così ho appena aggiungo la mia nota su implementazione predefinita di hash
. Eccolo:
-(unsigned)hash {return (unsigned)self;}
cioè è proprio lo stesso valore del puntatore che viene utilizzato in isEqual:
. Ecco come è possibile controllare questo fuori:
NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@",obj);
NSLog(@"hash: %x",obj.hash);
Il risultato sarà qualcosa di simile a questo:
obj: <NSObject: 0x16d44010>
hash: 16d44010
Con i migliori saluti.
A proposito di iOS 8 hash
è diventato un non di proprietà di un metodo, ma è lì.
presumo che NSObject
isEquals
utilizza l'operatore ==
, e hash
utilizza l'indirizzo di memoria.
metodo isEquals
non dovrebbe mai usa hash
come un test assoluto per l'uguaglianza. E 'garantito per avere due oggetti aventi hashCode
simile, se si cerca oggetti a sufficienza (basta creare più di 2 ^ 32 oggetti diversi, e almeno due di loro avrà lo stesso hash
).
In altre parole, hash
richiede le seguenti specifiche: Se due oggetti sono uguali, allora la loro hash
deve essere uguale; Tuttavia, se i valori hash
due degli oggetti sono uguali, essi non sono necessariamente uguali.
Come una punta, è sempre necessario eseguire l'override isEquals
e hashCode
insieme.