Qual é o NSObject isEqual: e função hash padrão?
-
12-09-2019 - |
Pergunta
Eu tenho uma classe de modelo de banco de dados que é um NSObject
. Eu tenho um conjunto desses objetos em um NSMutableArray
. Eu uso indexOfObject:
para encontrar uma correspondência. O problema é que as mudanças de endereço de memória do objeto modelo. Então, eu estou substituindo o método hash
para retornar do modelo ID de linha. Este, porém, não corrigi-lo. Eu também tenho que substituir o método isEqual:
para comparar o valor do método hash
.
O que faz o uso do método isEqual:
para determinar a igualdade por padrão?
Eu estou supondo que ele usa o endereço de memória. Depois de ler o isEqual:
documentação pensei que utilizou o valor do método hash
. Obviamente, isso não é o caso, como a minha tentativa de substituir esse valor não resolver o meu problema inicial.
Solução
Como você adivinhou corretamente, o comportamento NSObject
padrão do isEqual:
está comparando o endereço de memória do objeto. Estranhamente, este não é actualmente documentados no NSObject Classe referência, mas está documentado no documentação Introspecção , que afirma:
A implementação
NSObject
padrão deisEqual:
simplesmente verifica para a igualdade de ponteiro.
Claro que, como você é, sem dúvida, ciente, subclasses de NSObject
pode substituir isEqual:
a se comportar de forma diferente. Por exemplo, o método NSString
de isEqual:
, quando passou outro NSString
, irá verificar primeiro o endereço e, em seguida, verificar se há uma correspondência literal exata entre as cordas.
Outras dicas
A resposta sobre a implementação padrão de isEqual:
é um abrangente. Então, eu só acrescentar a minha nota sobre implementação padrão de hash
. Aqui está:
-(unsigned)hash {return (unsigned)self;}
i é apenas o mesmo valor de ponteiro que é usado em isEqual:
. Veja como você pode verificar isso:
NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@",obj);
NSLog(@"hash: %x",obj.hash);
O resultado será algo como isto:
obj: <NSObject: 0x16d44010>
hash: 16d44010
Atenciosamente.
BTW no iOS 8 hash
tornou-se uma propriedade não é um método, mas ele está lá.
Eu diria que NSObject
isEquals
usa o operador ==
e hash
usa o endereço de memória.
método isEquals
deve nunca usa hash
como um teste absoluto para a igualdade. É garantido para ter dois objetos com hashCode
semelhante, se você procurar por objetos suficientes (apenas criar mais de 2 ^ 32 objetos diferentes, e pelo menos dois deles terá o mesmo hash
).
Em outras palavras, hash
requer a seguinte especificação: Se dois objetos são iguais, então a sua hash
precisa ser igual; no entanto, se os valores hash
dois objetos são iguais, eles não são necessariamente iguais.
Como uma dica, você sempre deve substituir isEquals
e hashCode
juntos.