简体   繁体   中英

Should I use `weak self` when making asynchronous network request?

Here is my method to fetch some data from the network:

func fetchProducts(parameters: [String: Any],
                success: @escaping ([Product]) -> Void) 

As you noticed, it has escaping closure. Here is how I call above method in ViewModel:

service.fetchProducts(parameters: params, success: { response in
        self.isLoading?(false)
        /// doing something with response
}) 

The question is should I capture self weakly or strongly? Why? I think I can capture it strongly. Because, fetchProducts is a function which has closure as a parameter. But, I might be wrong. But, from other perspective, I think it should be weak. Because, ViewModel has strong reference to service , service has strong reference to success closure which has strong reference to self (which is ViewModel). It creates retain cycle. But deinit of ViewModel is called anyway, after ViewController which owns ViewModel is deinitialized. It means that there was no retain cycle. Why?

As long as your viewmodel is a class, you have to capture self weakly, otherwise you'll have a strong reference cycle. Since fetchProducts is asynchronous, its success closure might be executed after your viewmodel has already been deallocated - or would have been deallocated if the closure wasn't holding a strong reference to it. The strong reference in the async closure will block the viewmodel from being deallocated.

If you call service.fetchProducts in a class AND access self inside the async closure, you do need [weak self] . If you were to do this in a value type ( struct or enum ) OR if you didn't access self inside the closure, you don't need [weak self] - in a value type, you cannot even do [weak self] .

service.fetchProducts(parameters: params, success: { [weak self] response in
        self?.isLoading?(false)
        /// doing something with response
}) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM