Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

Как вы правильно догадались, поведение NSObject default isEqual: сравнивает адрес памяти объекта. Как ни странно, это не описано в NSObject Class Reference, но оно описано в Introspection, в которой говорится:

Стандартная реализация NSObject isEqual: просто проверяет равенство указателя.

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

Ответ 2

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

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

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

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

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

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

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

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

Ответ 3

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

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

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

В качестве подсказки вы всегда должны переопределять isEquals и hashCode вместе.