Как Apple реализовала NSSet?
Документы Apple в настоящее время НЕ ДОКУМЕНТАЮТ концепцию "идентичности" NSSet.
У меня есть некоторые ошибки, которые появляются из кода Apple. Например, "[NSMutableSet minusSet]" никогда не работает для меня, как описано в документации, но я уверен, что это из-за "идентичности".
containsObject:
Возвращает логическое значение, которое указывает, присутствует ли данный объект в наборе.
ДА, если anObject присутствует в наборе, иначе НЕТ.
Что это значит?
К вашему сведению, я попробовал:
- реализовано "isEqual:" на всех классах в наборе
- проверил, что все классы являются одним и тем же классом (нет путаницы подкласса / суперкласса)
- реализовал NSCopying на всех классах в наборе (без эффекта)
2 ответа
В Какао равенство объектов осуществляется с помощью isEqual:
а также hash:
Из заметок для isEqual:
:
Если два объекта равны, они должны иметь одинаковое хеш-значение. Этот последний пункт особенно важен, если вы определяете isEqual: в подклассе и намереваетесь поместить экземпляры этого подкласса в коллекцию. Убедитесь, что вы также определили хэш в своем подклассе.
Ваши подклассы должны будут реализовать оба из них, чтобы они возвращали одно и то же. Как только они это сделают, их можно будет правильно использовать в коллекциях какао.
Причина ваша NSSet
равенство не сработает, потому что наборы используют хэши (они хранятся в виде хеш-таблицы), следовательно, если вы только реализовали isEqual:
тогда есть шанс (хороший шанс), что их хеши будут другими.
NSSet
это хэш-набор в классическом смысле, поэтому вы должны реализовать hash
метод, чтобы убедиться, что объекты распознаются как равные. По умолчанию, hash
просто возвращает указатель объекта, приведенного к целому числу без знака, которое уникально для каждого объекта, поэтому даже объекты, которые возвращают true для isEqual:
не будет признан как таковой. Если вы заинтересованы в работе NSSet
Вы можете взглянуть на CFSet
исходный код, который является бесплатной встречной частью основного фонда NSSet
,