Ответ
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-циклов.
Ответ 18+ 🔞
Смотри, вот тебе про эту штуку — NSHashTable. Ну, типа как NSSet, но с прибамбасами, которые могут твою жопу спасти в особо запущенных случаях. В общем, коллекция, но не простая, а с изюминкой, блядь.
Чем она от обычного сета отличается, спросишь?
- Памятью рулит по-своему. Может держать объекты на слабых (weak) ссылках, понимаешь? Это значит, если объект на том свете — его из коллекции выкинут автоматом. Красота для всяких кешей или списков подписчиков, чтобы циклами не заёбываться.
- Гибкая, как гимнастка. Может запихнуть не только объекты, но и вообще левые указатели, если через
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 (ну или скоро будет, система подотрет)
А ещё её по-разному можно скрутить:
// Сильные ссылки, почти как сет, но без копирования
let strongTable = NSHashTable<AnyObject>(options: .strongMemory)
// Таблица, которая сравнивает по значению (ну, для особо дотошных)
let pointerTable = NSHashTable<NSString>(options: .copyIn)
Короче, зачем это всё? Ну, например, чтобы сделать свой велосипед для наблюдателей, где подписчики не будут висеть мёртвым грузом, если их уже никто не держит. Удобная, блядь, штука, когда нужно нестандартно подойти.