@brooklyn
Циклические ссылки в замыканиях в Swift создаются, когда замыкание и объект, на который замыкание ссылается, держат друг друга, предотвращая освобождение памяти. Для решения этой проблемы используется ключевое слово weak или unowned в списке захвата. Вот как это делается:
weak или unowned захватаКогда вы создаете замыкание внутри объекта, которое ссылается на self, вы можете предотвратить сильную ссылку с помощью использования списка захвата.
weak
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class MyClass {
var name: String = "Swift"
lazy var printName: () -> Void = { [weak self] in
guard let self = self else { return }
print("Name: (self.name)")
}
deinit {
print("MyClass is being deinitialized")
}
}
var instance: MyClass? = MyClass()
instance?.printName()
instance = nil // Объект будет корректно освобожден
|
В этом примере self захватывается как weak, что позволяет объекту корректно освобождаться из памяти при обнулении ссылки.
unownedunowned используется, если вы уверены, что объект, на который идет ссылка, будет существовать на момент вызова замыкания, например, для предотвращения разыменования nil.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class MyClass {
var name: String = "Swift"
lazy var printName: () -> Void = { [unowned self] in
print("Name: (self.name)")
}
deinit {
print("MyClass is being deinitialized")
}
}
var instance: MyClass? = MyClass()
instance?.printName()
instance = nil // Объект будет корректно освобожден
|
weak и unownedПравильное решение зависит от логики вашего кода и структуры его объектов. Учитывайте время жизни объектов, чтобы выбрать подходящий способ избежать утечек памяти.