简体   繁体   English

进行异步网络请求时是否应该使用“弱自我”?

[英]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:这是我在 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?问题是我应该弱地还是强地捕捉self Why?为什么? I think I can capture it strongly.我想我可以强烈地捕捉到它。 Because, fetchProducts is a function which has closure as a parameter.因为, fetchProducts是一个以闭包为参数的函数。 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).因为, ViewModel 对service有很强的引用, servicesuccess闭包有很强的引用,而success闭包对self (也就是 ViewModel)有很强的引用。 It creates retain cycle.它创建了保留循环。 But deinit of ViewModel is called anyway, after ViewController which owns ViewModel is deinitialized.但是,在deinit拥有 ViewModel 的ViewController之后,无论如何都会调用 ViewModel 的 deinit。 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.只要你的viewmodel是一个类,你就必须弱捕获self,否则你会有一个强引用循环。 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.由于fetchProducts是异步的,它的成功闭包可能会您的 viewmodel 已经被释放执行 - 或者如果闭包没有对它的强引用就会被释放。 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] .如果您在类中调用service.fetchProducts并在异步闭包中访问self ,则确实需要[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] .如果您要在值类型( structenum )中执行此操作,或者如果您没有在闭包内访问self ,则不需要[weak self] - 在值类型中,您甚至不能执行[weak self] .

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果我使用单一网络服务发出网络请求,是否需要使用[弱自我]? - Do I need to use [weak self] if I'm making a network request using a singleton networking service? 我应该在变量中使用弱自我吗? - Should I use weak self in variable? 如果“ self”是ViewController,您是否应该几乎总是使用[weak self]? - If “self” is the ViewController, should you almost always use [weak self]? 我什么时候甚至应该迅速将弱引用用于类的对象? - When or should i even use the weak reference for an object of a class in swift? 我什么时候应该使用“self”关键字? - When should I use the “self” keyword? 我不应该使用(非原子,弱)UIViewController属性吗? - Should I not use (nonatomic, weak) for UIViewController property? 什么时候应该在闭包中使用捕获列表,什么时候应该使用弱无主vs.无主? - When should i use capture list in closure, and when to use weak vs. unowned? 弱自我在异步关闭Alamofire中始终为零 - weak self always nil in asynchronous closure Alamofire 可选关闭是否总是 escaping? 我们应该在上面使用[weak self]还是[unowned self]? - Is optional closure always escaping? Should we use [weak self] or [unowned self] on it? 编写类别时,我应该使用self还是类别名称 - When writing a category, should i use self or the category name
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM