Что такое NSHashTable в iOS/macOS?

«Что такое NSHashTable в iOS/macOS?» — вопрос из категории Управление памятью, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

NSHashTable — это изменяемая коллекция, аналогичная NSSet, но с расширенными и настраиваемыми возможностями управления памятью и сравнения объектов.

Ключевые отличия от NSSet:

  • Управление памятью: Может хранить объекты со слабыми (weak) ссылками, что позволяет объектам автоматически удаляться из коллекции при деаллокации. Это полезно для кешей или списков наблюдателей.
  • Гибкость: Может хранить не только объекты (AnyObject), но и произвольные указатели (через NSPointerFunctions).
  • Поведение: Не копирует добавляемые объекты и не требует, чтобы они соответствовали протоколу NSCopying.

Пример использования со слабыми ссылками:

// Создание хэш-таблицы со слабыми ссылками на объекты
let weakTable = NSHashTable<AnyObject>(options: .weakMemory)

var object: NSObject? = NSObject()
weakTable.add(object!)

print(weakTable.contains(object!)) // true

object = nil // Объект деаллоцируется

// Коллекция автоматически очищается
print(weakTable.allObjects.count) // 0 (или будет в ближайшее время)

Другие варианты инициализации:

// Таблица с сильными ссылками (как NSSet, но без копирования)
let strongTable = NSHashTable<AnyObject>(options: .strongMemory)

// Таблица, которая сравнивает объекты по значению (pointer personality)
let pointerTable = NSHashTable<NSString>(options: .copyIn)

Основное применение: Создание кастомных коллекций со слабыми ссылками, например, для реализации паттерна «Наблюдатель» без создания retain-циклов.