Как Unowned ссылка работает с переменными захвата в Swift

Да, но только с классами нового стиля . Используйте функцию super() :

class Foo(Bar):
    def baz(self, arg):
        return super(Foo, self).baz(arg)

1
задан salman siddiqui 6 March 2019 в 05:52
поделиться

2 ответа

, что означает, что он содержит сильную ссылку на экземпляр RetainCycle

Это не так. У него есть неизвестная ссылка на экземпляр RetainCycle. Это не то же самое, что сильная ссылка.

Но я хочу понять, какой сценарий не будет взаимно освобожден одновременно, и Unowned self становится равным nil. Я просто хочу его завершить .?

В любое время 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] также не всегда является ответом.

0
ответ дан Rob Napier 6 March 2019 в 05:52
поделиться

Как я понимаю, вы спрашиваете, как «я» может быть нулевым, пока работает closue. Если я правильно понимаю, я могу привести вам довольно похожий пример, который я видел раньше.

Я написал расширение для UIImageView, которое загружает изображение по заданной ссылке и устанавливает себя следующим образом.

public extension UIImageView{
  func downloadImage(link: String){
    let url = URL(string:link)
    URLSession.shared.dataTask(with: url){ [unowned self]
      if let image = UIImage(data: data){
        DispatchQueue.main.async{
          self.image = image
        }
      }
    }
    task.start()
  }
}

Но была проблема. Загрузка изображения является фоновой задачей. Я установил метод завершения на UrlSession и увеличил его счетчик ссылок. Таким образом, мое закрытие остается, даже если imageView отключен.

Так что же произойдет, если я закрою свой viewController, в котором хранится мой UIImageView, до завершения загрузки. Он падает из-за того, что imageView освобожден, но закрытие все еще остается и пытается достичь своего свойства image. Как я понимаю, вы хотите научиться этому.

Я изменил ссылку unowned на weak, чтобы решить эту проблему.

0
ответ дан Ekrem Duvarbasi 6 March 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: