Наборы: неупорядоченные наборы объектов

Набор является неупорядоченным набором объектов, как показано на рисунке 1. Можно использовать наборы в качестве альтернативы массивам, когда порядок элементов не важен и производительность тестирования, является ли объект в наборе, важно. Даже при том, что массивы упорядочиваются, тестирование их для членства медленнее, чем тестирование наборов.

  Пример рисунка 1 подан

Основные принципы набора

NSSet объект управляет неизменным набором отдельных объектов — т.е. после создания набора Вы не можете добавить, удалить или заменить объекты. Можно, однако, изменить сами отдельные объекты (если они поддерживают модификацию). Переменчивость набора не влияет на переменчивость объектов в наборе. Если набор редко изменяется или изменяет оптовую торговлю, необходимо использовать неизменный набор.

NSMutableSet, подкласс NSSet, непостоянный набор отдельных объектов, позволяющий дополнение и удаление записей в любое время, автоматически выделяя память по мере необходимости. Необходимо использовать непостоянный набор, если набор изменяется инкрементно или является очень большим — поскольку большое количество занимает больше времени для инициализации.

NSCountedSet, подкласс NSMutableSet, непостоянный набор, к которому можно добавить определенный объект несколько раз; другими словами, элементы набора не обязательно отличны. Считаемый набор также известен как сумка. Набор сохраняет счетчик связанным с каждым отдельным объектом вставленный. NSCountedSet объекты отслеживают объекты числа раз, вставляются и требуют, чтобы объекты были удалены то же число раз для завершенного удаления объекта из набора. Таким образом, даже если объект был добавлен многократно, существует только один экземпляр объекта в считаемом наборе. countForObject: метод возвращает число раз, указанный объект был добавлен к этому набору.

Объекты в наборе должны ответить на NSObject методы протокола hash и isEqual: (см. NSObject для получения дополнительной информации). Если непостоянные объекты хранятся в наборе, любой hash метод объектов не должен зависеть от внутреннего состояния непостоянных объектов, или непостоянные объекты не должны быть изменены, в то время как они находятся в наборе. Например, непостоянный словарь может быть помещен в набор, но Вы не должны изменять его, в то время как это находится в там. (Обратите внимание на то, что может быть трудно знать, является ли данный объект в наборе).

NSSet обеспечивает много методов инициализатора, такой как setWithObjects: и initWithArray:, тот возврат NSSet объект, содержащий элементы (если таковые имеются), Вы передаете в как параметры. Объекты, добавленные к набору, не копируются (если Вы не передаете YES как параметр initWithSet:copyItems:). Скорее сильная ссылка к объекту добавляется к набору. Для получения дополнительной информации о копировании и управлении памятью, посмотрите Копирование Наборов.

Наборы, исключая NSCountedSet, предпочтительные наборы, если Вы хотите быть уверенными, что никакой объект не представлен несколько раз, и нет никакого результирующего эффекта для добавления объекта несколько раз.

Непостоянные наборы

Можно создать NSMutableSet объект с помощью любого из инициализаторов, предоставленных NSSet. Можно создать NSMutableSet объект от экземпляра NSSet (или наоборот) использование setWithSet: или initWithSet:.

NSMutableSet класс обеспечивает методы для добавления объектов к набору:

NSMutableSet класс дополнительно обеспечивает эти методы для удаления объектов из набора:

Поскольку NSCountedSet подкласс NSMutableSet, это наследовало все эти методы. Однако некоторые из них ведут себя немного по-другому с NSCountedSet. Например:

Используя наборы

NSSet класс обеспечивает методы для запросов элементов набора:

NSSet метод objectEnumerator позволяет Вам пересечь элементы набора один за другим. ИmakeObjectsPerformSelector: и makeObjectsPerformSelector:withObject: методы предусматривают отправку сообщений на отдельные объекты в наборе. В большинстве случаев быстрое перечисление должно использоваться, потому что это быстрее и более гибко, чем использование NSEnumerator или makeObjectsPerformSelector: метод. Для больше на перечислении, посмотрите Перечисление: Пересечение Элементов Набора.

Хэш-таблицы

NSHashTable класс сконфигурирован по умолчанию для содержания объектов во многом как NSMutableSet делает. Это также позволяет дополнительные возможности хранения, которые можно адаптировать для конкретных случаев, такой как тогда, когда Вам нужны усовершенствованные опции управления памятью, или когда Вы хотите содержать определенный тип указателя. Например, таблица карты на рисунке 2 сконфигурирована для содержания слабых ссылок на ее элементы. Можно также указать, хотите ли Вы скопировать объекты, ввел в набор.

  Монопольное использование объекта Хэш-таблицы рисунка 2

Можно использовать NSHashTable возразите, когда Вы хотите неупорядоченный набор элементов, использующий слабые ссылки. Например, предположите, что у Вас есть глобальная хэш-таблица, содержащая некоторые объекты. Поскольку глобальные объекты никогда не собираются, ни одно из его содержания не может быть освобождено, если они не сохранены слабо. Хэш-таблицам, сконфигурированным для содержания объектов слабо, не принадлежит их содержание. Если нет никаких сильных ссылок к объектам в такой хэш-таблице, те объекты освобождены. Например, хэш-таблица на рисунке 2 содержит слабые ссылки на свое содержание. Объекты A, C, и Z будут освобождены, но остается остальная часть объектов.

Для создания хэш-таблицы инициализируйте его с помощью initWithOptions:capacity: метод и надлежащие опции функций указателя. Также можно инициализировать его использование initWithPointerFunctions:capacity: и надлежащие экземпляры NSPointerFunctions. Для получения дополнительной информации о различных опциях функций указателя посмотрите Опции Функции Указателя.

NSHashTable класс также определяет hashTableWithWeakObjects конструктор удобства для создания хэш-таблицы со слабыми ссылками на ее содержание. Если Вы храните объекты, это должно только использоваться.

Для конфигурирования хэш-таблицы для использования произвольных указателей инициализируйте его с обоими NSPointerFunctionsOpaqueMemory и NSPointerFunctionsOpaquePersonality опции. При использовании хэш-таблицы для содержания произвольных указателей C функционируют API для void * указатели должны использоваться. Для получения дополнительной информации см. Хэш-таблицы. Например, можно добавить указатель на int значение с помощью подхода, показанного в Перечислении 1.

  Хэш-таблица перечисления 1 сконфигурирована для необъектных указателей

NSHashTable *hashTable=[[NSHashTable alloc] initWithOptions:
    NSPointerFunctionsOpaqueMemory |NSPointerFunctionsOpaquePersonality
    capacity: 1];
 
NSHashInsert(hashTable, someIntPtr);

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