Проверяет ли NSSet containsObject: на равенство указателей или равенство значений?

Скажем, у меня есть NSSet со строкой. Если я отправлю containsObject: с другой строкой, которая является другим указателем, но точно таким же строковым значением, будет ли возвращено YES?

Кроме того, та же история, когда дело доходит до removeObject:? То есть разные объекты с разными указателями, но с одинаковыми строковыми значениями вызовут удаление?


person Chris    schedule 07.12.2011    source источник
comment
Вы пробовали? У вас есть основания полагать, что это не так?   -  person jscs    schedule 07.12.2011
comment
Если он считает, что две строки с одинаковым содержимым являются одним и тем же объектом, вы не можете включить вторую строку в набор, поэтому часть вопроса removeObject: является спорной. NSSet утверждает, что предоставляет статические наборы различных объектов, а не статические наборы неравных объектов.   -  person Jeff Laing    schedule 07.12.2011
comment
Да, это работает. Можно подтвердить тесты containsObject для одинаковых строк. Я использовал его для оптимизации обновлений основных данных, поэтому мне не нужно каждый раз искать объект, чтобы узнать, существует ли он. Я просто использую свое ключевое поле, которое представляет собой строку.   -  person SpaceTrucker    schedule 15.08.2016


Ответы (1)


-containsObject: использует -isEqual:-hash) для проверки равенства. Это относится и к -removeObject:, и к любым другим операциям в NSSet, зависящим от некоторого понятия равенства.

person Lily Ballard    schedule 07.12.2011
comment
Где это задокументировано? Из того, что я вижу, ясно, что CFSet использует равенство POINTER по умолчанию, но я не вижу, чтобы NSSet разъяснял, что он использует? - person Jeff Laing; 07.12.2011
comment
@user: -[NSSet member:] говорит, что он использует isEqual:; member является одним из фундаментальные методы множества, и кажется, что подразумевается (хотя, вы правы, не явно), что containsObject: использует member. - person jscs; 07.12.2011
comment
@ user256413: Все методы NSSet, основанные на равенстве, по определению должны использовать один и тот же тест на равенство. CFSet будет использовать равенство указателя, если вы не укажете другую функцию равенства. Если вы используете kCFTypeSetCallBacks, то он использует CFEqual() в качестве сравнения на равенство. - person Lily Ballard; 07.12.2011
comment
Спасибо, я надеялся, что он использует isEqual. Спасибо, что прояснили это - person Chris; 08.12.2011
comment
Может кто-нибудь объяснить это (извините за форматирование): NSMutableString *str = [NSMutableString stringWithString:@"Hello"]; NSSet *set = [NSSet setWithObject:str]; NSLog(@"%d", [set containsObject:str]); // returns 1 [str appendString:@"BLA"]; NSLog(@"%d", [set containsObject:str]); // returns 0 NSLog(@"%d", [set.allObjects containsObject:str]); // returns 1 - person jowie; 24.04.2014
comment
@jowie: NSSet — это хеш-таблица. -[NSMutableString hash] зависит от содержимого строки. Изменение строки, когда она находится в наборе, явно не поддерживается (так же, как и изменение, когда она находится в NSDictionary), потому что это изменяет хэш, что приводит к сбою поиска. Однако set.allObjects создает NSArray, который не использует hash. - person Lily Ballard; 25.04.2014
comment
Интересно, что он меняет хэш. Почему это происходит? - person jowie; 25.04.2014
comment
@jowie: Потому что альтернатива состоит в том, чтобы каждый NSMutableString имел один и тот же хэш, что привело бы к абсолютно ужасной производительности при сохранении в словарях/наборах. Простое правило: вы не должны изменять объект, который был помещен в NSSet или использован в качестве ключа для NSDictionary. - person Lily Ballard; 26.04.2014
comment
Так будет ли правильной аналогией сказать, что NSSet похож на NSDictionary только для ключа (точно так же, как NSArray немного похож на NSDictionary только для значения)? Потому что NSSet элементы уникальны, как NSDictionary ключи? - person jowie; 29.04.2014
comment
@jowie: NSSet фактически является NSDictionary, не имеющим значения, это правильно. Но нет, NSArray не имеет ничего общего с NSDictionary, состоящим только из значений (помимо всех различий в производительности, NSDictionary не отсортированы, а NSArray отсортированы). - person Lily Ballard; 30.04.2014