@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
, что позволяет объекту корректно освобождаться из памяти при обнулении ссылки.
unowned
unowned
используется, если вы уверены, что объект, на который идет ссылка, будет существовать на момент вызова замыкания, например, для предотвращения разыменования 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
Правильное решение зависит от логики вашего кода и структуры его объектов. Учитывайте время жизни объектов, чтобы выбрать подходящий способ избежать утечек памяти.