Что такое NSObject isEqual:и хеш-функция по умолчанию?

StackOverflow https://stackoverflow.com/questions/1241575

  •  12-09-2019
  •  | 
  •  

Вопрос

У меня есть класс модели базы данных, который представляет собой NSObject.У меня есть набор этих объектов в NSMutableArray.я использую indexOfObject: чтобы найти совпадение.Проблема заключается в изменении адреса памяти объекта модели.Поэтому я переопределяю hash метод для возврата идентификатора строки модели.Однако это не исправляет ситуацию.Мне также нужно переопределить isEqual: метод сравнения стоимости hash метод.

Что это isEqual: использовать метод для определения равенства по умолчанию?

Я предполагаю, что он использует адрес памяти.После прочтения isEqual: документации, я думал, что она использовала значение из hash метод.Очевидно, что это не так, поскольку моя попытка переопределить это значение не решила мою первоначальную проблему.

Это было полезно?

Решение

Как вы правильно догадались, NSObjectпо умолчанию isEqual: поведение сравнивает адрес памяти объекта.Как ни странно, в настоящее время это не задокументировано. Справочник по классу NSObject, но это задокументировано в Самоанализ документация, в которой указано:

По умолчанию NSObject реализация isEqual: просто проверяет равенство указателей.

Конечно, как вы, несомненно, знаете, подклассы NSObject может переопределить isEqual: вести себя по-другому.Например, NSString's isEqual: метод, когда передается другой NSString, сначала проверит адрес, а затем проверит точное буквальное совпадение между строками.

Другие советы

Ответ о реализации по умолчанию isEqual: является всеобъемлющим.Поэтому я просто добавляю свое примечание о реализации по умолчанию hash.Вот:

-(unsigned)hash {return (unsigned)self;}

То есть это то же самое значение указателя, которое используется в isEqual:.Вот как вы можете это проверить:

NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@",obj);
NSLog(@"hash: %x",obj.hash);

Результат будет примерно таким:

obj: <NSObject: 0x16d44010>
hash: 16d44010

С наилучшими пожеланиями.

Кстати, в iOS 8 hash стал свойством, а не методом, но он есть.

Я бы предположил, что NSObject isEquals использует == оператор и hash использует адрес памяти.

isEquals метод никогда не должен использовать hash как абсолютный критерий равенства.Гарантировано наличие двух объектов, имеющих одинаковые значения. hashCode, если вы ищете достаточно объектов (просто создайте более 2^32 разных объектов, и как минимум два из них будут иметь одинаковые hash).

Другими словами, hash требуется следующая спецификация:Если два объекта равны, то их hash должен быть равным;однако, если два объекта hash значения равны, они не обязательно равны.

Совет: всегда следует переопределять isEquals и hashCode вместе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top