这是我从网络获取一些数据的方法:
func fetchProducts(parameters: [String: Any],
success: @escaping ([Product]) -> Void)
正如您所注意到的,它具有转义关闭。以下是我在ViewModel中调用上述方法的方式:
service.fetchProducts(parameters: params, success: { response in
self.isLoading?(false)
/// doing something with response
})
问题是我应该弱self
还是强?为什么?我想我可以强烈地捕捉它。因为,fetchProducts
是一个以闭包为参数的函数。但是,我可能是错的。但是,从其他角度来看,我认为它应该是薄弱的。因为,ViewModel 对service
有很强的引用,service
对闭包有很强的引用success
闭包,闭包对self
有很强的引用(即 ViewModel)。它创造了保留周期。但是deinit
的 ViewModel 还是被调用,在ViewController
拥有 ViewModel 的被取消初始化之后。这意味着没有保留周期。为什么?
只要你的视图模型是一个类,你就必须弱地捕捉自我,否则你就会有很强的参考循环。由于fetchProducts
是异步的,因此它的成功闭包可能会在视图模型已经解除分配后执行 - 或者如果闭包没有对它的强引用,则会被解除分配。异步闭包中的强引用将阻止视图模型被解除分配。
如果在异步闭包中调用类 AND 访问self
中的service.fetchProducts
,则确实需要[weak self]
。如果你要在值类型(struct
或enum
)中执行此操作,或者如果你没有在闭包中访问self
,你不需要[weak self]
- 在值类型中,你甚至不能做[weak self]
。
service.fetchProducts(parameters: params, success: { [weak self] response in
self?.isLoading?(false)
/// doing something with response
})