NSSet и NSCountingSet, когда лучше всего их использовать? - PullRequest
9 голосов
/ 22 мая 2009

Эти два типа коллекций используются мной редко, так как я обычно использую их встречные части, NSArray, NSDictionary и эквивалентные изменяемые таблицы. У меня такое чувство, что я упускаю коллекцию, которая может действовать намного быстрее, чем две другие в определенных ситуациях. Когда идеальное время для их использования и как?

Ответы [ 3 ]

14 голосов
/ 22 мая 2009

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

То же самое относится к NSCountedSet, хотя NSCountedSet также сохраняет количество дублированных объектов.

Итак, в двух словах: используйте набор, когда вас интересует проверка на членство , а не просто храните коллекцию объектов (некоторые из которых могут дублироваться, как решено методом isEqualTo какой-то).

11 голосов
/ 22 мая 2009

В продолжение midpadi, многие использования NSArray должны быть заменены на NSSet. NSSet - это коллекция уникальных объектов. NSArray - это коллекция упорядоченных объектов. Если ваши объекты не имеют собственного порядка и являются уникальными, вам следует использовать NSSet.

Я очень часто сохраняю NSSet на уровне модели и позволяю компонентам пользовательского интерфейса, которым требуется заказ, создавать свои собственные NSArrays. Например, рассмотрим случай «списка друзей», состоящего из «друзей». Список друзей сам неупорядочен; это просто коллекция. И объекты должны быть уникальными. Однако на уровне пользовательского интерфейса вам нужен порядок, и вы можете даже захотеть поместить одного и того же собеседника в несколько групп (например, «Избранное» и «Не в сети»). Но это проблемы пользовательского интерфейса, и уровень модели не должен беспокоиться о них.

NSSet *buddies = [buddyList allBuddies];
BOOL isBuddy = [buddyList containsObject:buddy];

NSArray *buddyList = [[buddyList allBuddies] sortedAraryUsingSelector:[self buddySortSelector]];

Когда появляется новый друг, BuddyList публикует уведомление (BuddyListDidAddBuddiesNotification), которое включает в себя NSSet добавленных друзей в его userInfo. Таким образом, элементы пользовательского интерфейса, которые наблюдают за этим, могут вставлять друзей в свои списки в любом порядке сортировки. Это делает анимацию списка очень простой, что намного сложнее, если вы поддерживаете все отсортированные версии на уровне модели.

Когда у вас есть два NSSets, довольно легко выяснить различия между ними и создать серию удалений и добавлений, чтобы превратить одно в другое (опять же, полезно для анимации). С NSArray сделать это гораздо сложнее.

Поэтому я рекомендую по умолчанию использовать NSSet. Вы должны использовать NSArray только тогда, когда вам действительно нужен порядок. Это, к сожалению, наоборот, как это делают большинство людей.

4 голосов
/ 22 мая 2009

В дополнение к другим ответам, которые говорят в основном о наборах, но не так много о счетных наборах, вам может быть интересно, когда лучше использовать счетный набор. Подсчитанный набор полезен для таких вещей, как взвешивание или другие статистические алгоритмы: в конце вы можете в конечном итоге создать упорядоченный массив его содержимого, отсортированный с использованием сохраненного количества.

Другой вариант может быть в уникальных таблицах или в виде счетчика ссылок / сборщика мусора. Использование подсчитанного набора включило бы тесты для включения (т. Е. Возвращает существующий идентичный объект, а не создавал новый - аналогично тому, что делает CoreData внутри), одновременно выполняя своего рода подсчет ссылок на значения, которые он включает, поскольку объект был бы выпущен набором, когда его счет достигает 0.

...