Как в Swift добавить объект в коллекцию без увеличения счетчика сильных ссылок?

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

Ответ

Чтобы избежать увеличения счетчика сильных ссылок, нужно использовать коллекции, хранящие weak (слабые) или unowned ссылки. В чистом Swift для этого нужна специальная обертка.

Решение: Обертка Weak

class Weak<Object: AnyObject> {
    weak var value: Object?
    init(_ value: Object) {
        self.value = value
    }
}

// Использование
class MyClass {}
var weakContainer = [Weak<MyClass>]()
let object = MyClass()
weakContainer.append(Weak(object)) // Счетчик сильных ссылок на object НЕ увеличивается.

// При обращении нужно учитывать, что значение может стать nil
for weakRef in weakContainer {
    if let object = weakRef.value {
        // Работаем с object
    }
}

Альтернативы и примечания:

  • NSPointerArray (из Objective-C): Может быть сконфигурирован для хранения weak-указателей.
  • NSHashTable / NSMapTable: Foundation-коллекции с опциями хранения weak-объектов.
  • Слабые ссылки автоматически обнуляются (nil), когда объект освобождается. Это необходимо всегда проверять перед использованием.
  • Такой подход часто используется для реализаций паттернов вроде observer/listener, чтобы избежать циклов retain-ов.