问题描述
这是我从网络中获取一些数据的方法:
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)。它创建保留周期。但是在拥有ViewModel的deinit
被取消初始化之后,无论如何都会调用ViewModel的ViewController
。这意味着没有保留周期。为什么?
解决方法
只要您的视图模型是一个类,就必须弱捕获自己,否则您将拥有强大的引用周期。由于fetchProducts
是异步的,因此它的成功关闭可能在您的视图模型已经被释放后 执行,或者如果关闭没有对它的强大引用,则已经被释放了。异步关闭中的强引用将阻止视图模型被释放。
如果您在类中调用service.fetchProducts
并在异步闭包内访问self
,则确实需要[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
})