Разрешение цикла сильных ссылок с помощью слабой ссылки
👋 В прошлых статьях мы подробно рассмотрели природу возникновения цикла сильных ссылок с помощью наглядного примера.
🔗 В этой статье я хотел бы рассмотреть пример, как можно использовать слабые ссылки, чтобы избежать таких циклов.
Что такое слабая ссылка?
📖 Слабая ссылка (weak reference) — это ссылка, которая не удерживает сильной привязки к объекту, на который она ссылается. Это означает, что такая ссылка не мешает ARC (Automatic Reference Counting) освобождать объект, на который она указывает. В отличие от сильной ссылки, слабая ссылка не увеличивает счетчик удержания объекта.
Как использовать слабую ссылку?
👉 Для объявления слабой ссылки мы используем ключевое слово weak перед свойством или переменной. Поскольку слабая ссылка не удерживает объект, он может быть освобожден в любой момент, даже если существует слабая ссылка на него.
Следовательно, когда объект, на который ссылается слабая ссылка, освобождается, ARC автоматически присваивает ей значение nil. Из-за этой особенности слабые ссылки должны быть объявлены как переменные, а не константы, что позволяет им изменять свое значение на nil во время выполнения.
Пример использования слабой ссылки
👀 Давайте посмотрим, как слабые ссылки помогают разорвать цикл сильных ссылок.
👉 Возьмем пример с классами Car и Owner. Сделаем свойство car в классе Owner слабой ссылкой.
class Car { let brand: String var owner: Owner? init(brand: String) { self.brand = brand print("\(brand) is being initialized") } deinit { print("\(brand) is being deinitialized") } } class Owner { let name: String weak var car: Car? init(name: String) { self.name = name print("\(name) is being initialized") } deinit { print("\(name) is being deinitialized") } }
🔷 Теперь создадим экземпляры этих классов:
var volvo: Car? var artem: Owner? volvo = Car(brand: "Volvo") artem = Owner(name: "Artem")
🔗 На данный момент у каждого объекта есть по одной сильной ссылке.
🔶 Далее, как и раньше, присвоим значения свойствам:
volvo?.owner = artem artem?.car = volvo
🚘 В данном случае экземпляр Car по-прежнему имеет сильную ссылку на экземпляр Owner, в то время как экземпляр Owner теперь ссылается на экземпляр Car с использованием слабой ссылки. Это означает, что при обнулении переменной artem, которая указывает на экземпляр Car, сильные ссылки на этот экземпляр исчезнут.
Проверка работы кода
🔶 Чтобы убедиться в этом, сначала установим для volvo значение nil:
volvo = nil
Volvo is being initialized Artem is being initialized Volvo is being deinitialized
🔶 Как видим, объект Volvo был успешно освобожден.
🔷 Теперь установим artem в nil:
artem = nil
Volvo is being initialized Artem is being initialized Volvo is being deinitialized Artem is being deinitialized
🔷 Как видно, при освобождении artem, соответственно, деинициализируется и сам объект Owner.
✨ Надеюсь, данный пример помог вам лучше осознать концепцию слабых ссылок и их применение на практике.
❤️ Ставьте лайк, если хотите, чтобы подобные посты выходили чаще.