[英]Capturing self weak or unowned on asynchronous network requests
Whenever I am doing asynchronous network requests it could be that on arrival of the request self is already nil (eg the ViewController is already dismissed). 每当我做异步网络请求时,可能是在请求到达时self已经是nil(例如,ViewController已被解除)。
To prevent this I am usually capturing self as weak: 为了防止这种情况,我通常将自我视为弱者:
future.onSuccess(context: Queue.main.context, callback: { [weak self] result in
if let strongSelf = self {
// Do some stuff with self, which is now guaranteed to be not nil
// strongSelf.someMethod()
}
})
Or I could capture self as unowned: 或者我可以将自己视为无主:
future.onSuccess(context: Queue.main.context, callback: { [unowned self] result in
// Do some stuff with self
// self.someMethod()
})
I do not care about the request returning, because when the request is returning at a point in time when the ViewController is already dismissed I have nothing to show from the request. 我不关心请求返回,因为当请求在ViewController已被解除的时间点返回时,我没有从请求中显示任何内容。 So I do not want to keep self "alive" with the closure.
所以我不想让关闭时自我“活着”。
My question is now - is it enough to capture self as unowned in this case? 我现在的问题是 - 在这种情况下是否足以将自己视为无主? Or do I have to do all the time the nil checking with [weak self]?
或者我必须一直做[零自我]的零检查? What happens in case of unowned capturing with the request when it arrives and self is already nil - is the closure also still alive and would execute and would trigger a runtime error on accessing nil?
如果在请求到达并且self已经为零时无主捕获的情况下会发生什么 - 闭包是否仍然存在且将执行并且将在访问nil时触发运行时错误? Or would the closure also be deallocated together with self and the request would run into the "void"?
或者封闭也会与自己一起解除分配,请求会遇到“空白”?
Or can I forget both weak and unowned in this case because when self get's deallocated the closure will also be deallocated and so there is no danger of accessing nil on arrival of the request? 或者在这种情况下我可以忘记弱者和无人物,因为当自我取消分配时,闭包也将被解除分配,因此在请求到达时没有访问nil的危险吗?
PS: I know that there are already many questions-answers on this topic but I could not find an answer in the case I do not care about the async arrival. PS:我知道关于这个话题已经有很多问题 - 答案但是在我不关心异步到达的情况下我找不到答案。
If you capture self without weak
or unowned
keywords, your view controller will be retained by the closure and will not deallocate before the closure dies. 如果您在没有
weak
关键字或unowned
关键字的情况下捕获self,则视图控制器将由闭包保留,并且在闭包死亡之前不会释放。 The difference between weak
and unowned
is that weak
is an Optional and requires conditional binding as a safety check. 之间的区别
weak
和unowned
是, weak
是可选的,并要求有条件的结合作为安全检查。 On the other hand, unowned
is not as fail-safe. 另一方面,
unowned
并非故障安全。 It assumes that your view controller is still alive and it will crash if it is not. 它假定您的视图控制器仍处于活动状态,如果不存在则会崩溃。 For more information see this answer .
有关更多信息,请参阅此答案 。
You do not want to use unowned
in this case, because if the object is deallocated before the call finishes, you have a dangling reference that is not set to nil
. 在这种情况下,您不希望使用
unowned
,因为如果在调用完成之前取消分配对象,则您有一个未设置为nil
的悬空引用。 If you try to use this reference when the request finishes, the app will crash. 如果您在请求完成时尝试使用此引用,则应用程序将崩溃。
As an aside, if you really don't need the response anymore, you should also cancel the request when the view controller is deallocated. 另外,如果您确实不再需要响应,则还应在取消分配视图控制器时取消该请求。 If you use
NSURLSession
, you always get a NSURLSessionTask
reference which can be cancelled. 如果使用
NSURLSession
,则始终会获得可以取消的NSURLSessionTask
引用。 So, one would often combine the use of [weak self]
pattern in the closure with code that saves an additional weak reference to the NSURSessionTask
and have a deinit
conditionally cancel that. 所以,一个常常结合使用的
[weak self]
模式与代码封闭,节省了额外的弱参考NSURSessionTask
并有deinit
有条件地取消。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.