Использует ли NSSet хэш для определения уникальности?
Я работал в предположении, что NSSet использовал хеш для поиска потенциальных совпадений, а затем вызвал isEqual на каждом из них, чтобы проверить реальные столкновения, но я понял, что не могу найти никаких доказательств, подтверждающих это.
Причина, по которой я поднимаю это, - это существование метода "member:" в NSSet. Почему документация для участника: выйдите из своего пути, чтобы указать, что isEqual: используется для поиска вашего объекта, когда ничего не происходит в NSSet? Does containsObject: использовать хэш или что-то еще?
Может ли кто-нибудь подтвердить это поведение? И в идеале, справочная документация на нем?
Ответы
Ответ 1
Я бы предложил прочитать Темы программирования коллекций, в частности раздел "Наборы: неупорядоченные коллекции объектов". Там вы найдете следующую информацию:
Эта информация о производительности предполагает адекватные реализации хеша метод, определенный для объектов. С плохая хэш-функция, доступ и изменения взять линейное время.
и
Объекты в наборе должны отвечать на методы хэш-протокола протокола NSObject и isEqual: (см. NSObject для более Информация). Если изменяемые объекты хранится в наборе, либо хеш метод объектов не должен зависеть по внутреннему состоянию изменчивого объекты или изменяемые объекты не следует изменять, в то время как theyre in набор. Например, изменяемый словарь можно поместить в набор, но вы не должны изменять его, пока он находится в там. (Обратите внимание, что это может быть сложно знать, действительно ли данный объект находится в коллекции).
Итак, да, хэш и isEqual используются как вы предполагали.
Ответ 2
Я хотел бы войти и дать дополнительную информацию об использовании NSSet hash
и isEqual:
, так как в последнее время я обнаружил странные ошибки и обнаружил, что они были из-за меня с видом hash
.
Когда вы сохраняете пользовательские объекты в наборе, NSSet использует значение, возвращаемое вашим методом hash
, для группировки объектов в разных ячейках, в которых они сравниваются друг с другом с использованием соответствующего метода isEqual:
. Таким образом, hash
всегда будет вызываться на вашем объекте при вставке, создании, тестировании членства и т.д., И если этот объект попадает в корзину, где есть другие объекты, его метод isEqual
будет использоваться для того, чтобы отличить его от их.
Таким образом, hash
всегда должен быть одинаковым для объектов, которые считаются равными и, насколько это возможно, дают значения, которые будут равномерно распределять объекты. Последнее свойство гарантирует, что ящики будут как можно меньше, минимизируя вызовы на isEqual:
.