发出异步网络请求时,我应该使用“弱自我”吗?

问题描述

这是我从网络中获取一些数据的方法:

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]。如果您要使用值类型(structenum)来执行此操作,或者如果您没有在闭包内访问self,则不需要[weak self]-在值类型中,您甚至无法执行[weak self]

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...