快速代码的含义是什么?

时间:2018-08-29 09:48:23

标签: ios swift closures weak-references

谁能告诉我为什么我们使用guard let self = self

在阅读有关GCD的过程中,我已经看到了这段代码,我无法弄清该特定行的作用。

DispatchQueue.global(qos: .userInitiated).async { [weak self] in
    guard let self = self else {
        return
    }

    // ...
}

4 个答案:

答案 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。您也可以将其称为selfself块后面的guard变量实际上是与self不同的变量,只是名字相同。

所以意思是:

  

仅当self仍然有效时,才执行此块。 (否则,什么也不做。)

答案 2 :(得分:1)

async {}中的代码将异步执行。完成函数({ [weak self] ... })包含对调用async函数的对象的(默认强)引用。

由于它是异步的,因此您无法知道a)何时执行回调b)是否将执行回调。意味着强烈引用self可能会导致内存泄漏。

这就是为什么使用[weak self]传递弱引用的原因。由于调用是异步的,因此可能是,当最终执行回调时,ARC已经收集了对self的引用,因此self将是nil

然后最好在执行回调中的代码之前检查self是否仍然存在。

答案 3 :(得分:0)

正在创建一个线程并将其添加到全局队列中,并且在执行异步指令集之后,用户启动了QOS(服务质量,或者可以说该线程的优先级)(中等优先级)