слабый self может использоваться в DispatchQueue

#swift #memory #memory-leaks #grand-central-dispatch #ownership-semantics

#swift #память #утечки памяти #grand-central-dispatch #владение-семантика

Вопрос:

Вот простой класс API, как показано ниже.

 class API {
    func fetchData(_ callback: @escaping (Data) -> Void) {
        // reqeust to server...
        callback(response)
    }
}
 

Когда мы вызываем fetchData приведенный ниже код, мы используем [weak self] его для предотвращения циклов сохранения.
Я использую DispatchQueueue.main.async для обновления пользовательского интерфейса в основном потоке.
Нужно ли мне иметь [weak self] здесь тоже?
Какой из них правильный, fooA или fooB ?

 class MyViewController: UIViewController {
    let api = API()
    
    func fooA() {
        api.fetchData { [weak self] data in
            self?.doSomething()
            DispatchQueue.main.async { [weak self] in
                self?.updateUI(data)
            }
        }
    }
    
    func fooB() {
        api.fetchData { [weak self] data in
            self?.doSomething()
            DispatchQueue.main.async {
                self?.updateUI(data)
            }
        }
    }
}
 

Комментарии:

1. Нужно ли мне здесь также иметь [слабый self]? — нет, вы этого не делаете.

2. Конечно [weak self] , должно быть в 2 местах. Оба блока являются независимыми и асинхронными. вы можете получить завершение fetchData, запланировать выполнение updateUI, и прежде чем это успеет произойти, ваш контроллер представления готов умереть. Итак, чтобы умереть мирно, ему нужен этот второй [слабый self]

Ответ №1:

weak и unowned распространять:

 api.fetchData { [weak self] data in
  // do something with self
  DispatchQueue.main.async { // weak inherited
    // update UI with data
  }
}