, что означает, что он содержит сильную ссылку на экземпляр RetainCycle
Это не так.У него есть неизвестная ссылка на экземпляр RetainCycle.Это не то же самое, что сильная ссылка.
Но я хочу понять, какой сценарий не будет взаимно освобожден одновременно, и Unowned self становится равным нулю. Я просто хочу его завершить .?
В любое время closure
захватывается чем-то за пределами RetainCycle
, и поэтому переживает своего владельца:
var rc: RetainCycle? = RetainCycle() // create an RC
let cl = rc?.closure // Hold onto its closure
rc = nil // Deallocate the RC
cl?() // Access the closure safely, but its reference to `self` is invalid. Crash.
Как правило, замыкания, включающие unowned self
, должны быть невозможныдля ссылки за пределами self
.Иногда трудно понять, что это правда.Например, вот случай, когда недавно произошел сбой приложения, над которым я работаю:
var completion: (() -> Void)?
...
DispatchQueue.main.async { [unowned self] in
self.completion()
self.completion = nil
}
Это нормально, но если self
освобождается между временем, когда он ставит в очередь блок главной очереди, и временем, когдаблок бежит, бум.
Кстати, в этом случае правильный ответ будет обычным, сильным self
.Мы хотим, чтобы цикл сохранения удерживал этот объект до тех пор, пока не будет запущен обработчик его завершения, после чего блок исчезнет, ссылка на self
исчезнет, и self
будет должным образом освобожден.Так что [weak self]
тоже не всегда ответ.