谁能告诉我为什么我们使用guard let self = self
?
在阅读有关GCD的过程中,我已经看到了这段代码,我无法弄清该特定行的作用。
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else {
return
}
// ...
}
答案 0 :(得分:5)
首先,您要创建一个将异步执行的块
DispatchQueue.global(qos: .userInitiated).async
然后在代码块中检查调用此函数的对象self
是否仍被分配
guard let self = self else {
return
}
我们需要检查这一点,因为self在块内声明为weak
以避免保留周期(Swift closures causing strong retain cycle with self),并且可以在执行块之前将其释放。该行代码检查self是否为!= nil,并将其分配给self,否则返回。
答案 1 :(得分:3)
self
在此块中被声明为weak
,因此具有Optional
类型。例如。如果您的班级名称为MyViewController
,则该区块中的self类型为MyViewController?
。使用弱的原因是为了避免保留周期。仅当self仍然存在时,该块才应执行。因此,一种解决方案是:
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.makeFoo()
strongSelf.continueWithBar()
}
,但无需将其称为strongSelf
。您也可以将其称为self
。 self
块后面的guard
变量实际上是与self
不同的变量,只是名字相同。
所以意思是:
仅当
self
仍然有效时,才执行此块。 (否则,什么也不做。)
答案 2 :(得分:1)
async {}
中的代码将异步执行。完成函数({ [weak self] ... }
)包含对调用async
函数的对象的(默认强)引用。
由于它是异步的,因此您无法知道a)何时执行回调b)是否将执行回调。意味着强烈引用self
可能会导致内存泄漏。
这就是为什么使用[weak self]
传递弱引用的原因。由于调用是异步的,因此可能是,当最终执行回调时,ARC已经收集了对self
的引用,因此self
将是nil
。
然后最好在执行回调中的代码之前检查self
是否仍然存在。
答案 3 :(得分:0)
正在创建一个线程并将其添加到全局队列中,并且在执行异步指令集之后,用户启动了QOS(服务质量,或者可以说该线程的优先级)(中等优先级)