В чем разница между сильной (strong) и слабой (weak) ссылкой в управлении памятью Swift (ARC)?

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

Ответ

Сильная (strong) ссылка по умолчанию. Она удерживает объект в памяти, увеличивая его счетчик ссылок (retain count). Пока существует хотя бы одна сильная ссылка, объект не будет освобожден.

Слабая (weak) ссылка не удерживает объект. Она не увеличивает retain count. Если все сильные ссылки на объект исчезнут, он будет освобожден, а все слабые ссылки на него автоматически станут nil.

Пример:

class Person {
    let name: String
    init(name: String) { self.name = name; print("(name) создан") }
    deinit { print("(name) освобожден") }
}

var strongPerson: Person? = Person(name: "Анна") // Сильная ссылка, retain count = 1
weak var weakPerson: Person? = strongPerson      // Слабая ссылка, retain count остаётся = 1

print(weakPerson?.name) // Опциональная развертка: "Анна"

strongPerson = nil // Сильная ссылка разорвана, retain count = 0
// В консоли: "Анна освобожден"

print(weakPerson?.name) // weakPerson автоматически стал nil, выводит "nil"

Ключевые отличия и использование:

  • Сильная ссылка: Основной механизм владения объектом.
  • Слабая ссылка: Всегда объявляется как опциональная (var weak). Используется для разрыва циклов сильных ссылок (retain cycles), которые приводят к утечкам памяти. Типичные сценарии:
    • Делегаты (weak var delegate).
    • Замыкания, захватывающие self (используйте [weak self]).
    • Двунаправленные связи в родительско-дочерних иерархиях, где дочерний объект имеет слабую ссылку на родительский.