4

Here is a simple API class as shown below.

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

When we call fetchData in the code below, we use [weak self] to prevent retain cycles.
I'm using DispatchQueueue.main.async to update the UI in the main thread.
Do I need to have [weak self] here too?
Which one is right, fooA or 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)
            }
        }
    }
}
Eric Xue
  • 117
  • 1
  • 9
user3569109
  • 191
  • 8
  • *Do I need to have [weak self] here too?* - no, you don't. – Asperi Dec 13 '20 at 05:19
  • 2
    Of course `[weak self]` must be in 2 places. Both blocks are independent, and asynchronous. you may get completion of fetchData, schedule execution of updateUI, and before it has time to happen, your view controller is ready to die. So to die peacefully, it needs that second [weak self] – timbre timbre Dec 14 '20 at 04:53

1 Answers1

0

weak and unowned propagate:

api.fetchData { [weak self] data in
  // do something with self
  DispatchQueue.main.async { // weak inherited
    // update UI with data
  }
}
Eric Xue
  • 117
  • 1
  • 9