Ответ
weak и unowned ссылки решают проблему сильных циклических ссылок (strong reference cycles), которые приводят к утечкам памяти, так как Automatic Reference Counting (ARC) не может освободить объекты, ссылающиеся друг на друга.
Принцип работы:
weak— создает опциональную (Optional) ссылку, которая не увеличивает счетчик ссылок (retain count). Становитсяnil, когда целевой объект освобождается.unowned— создает неопциональную ссылку, которая также не увеличивает счетчик ссылок. Предполагает, что целевой объект будет существовать на протяжении всего времени жизни ссылки. Обращение кunownedссылке после освобождения объекта вызывает краш.
Пример проблемы и решения:
class Person {
var apartment: Apartment? // Сильная ссылка -> цикл
}
class Apartment {
var tenant: Person? // Сильная ссылка -> цикл
}
// Создание цикла:
var john: Person? = Person()
var unit4A: Apartment? = Apartment()
john?.apartment = unit4A
unit4A?.tenant = john // Цикл! Объекты никогда не освободятся.
// Решение с weak:
class Apartment {
weak var tenant: Person? // Weak ссылка разрывает цикл
}
Когда использовать:
- Используйте
weak, когда ссылка может статьnilв течение своего времени жизни (например, делегаты, дочерние ссылки в иерархии). - Используйте
unowned, когда ссылка никогда не станетnil, а время жизни целевого объекта равно или превышает время жизни ссылки (например, захват в замыкании, которое гарантированно выполнится до освобождения self).