swift 在函数中保留循环

swift retain cycle in function

请问在这种情况下是否会发生retain cycle:

func someFunc() {
    var aVar = SomeObj()
    funcWithClosure(something, completionHandler: { _ -> Void in
        aVar = SomeObj() // new
    })
}

在这种情况下,我从闭包中返回 aVar。我只是想知道这是否会创建一个保留周期。如果为真,我应该通过以下方式修复:

func someFunc() {
    var aVar = SomeObj()
    funcWithClosure(something, completionHandler: { [weak aVar] _ -> Void in
        aVar = SomeObj() // new
    })
}

不,不是。闭包持有对 aVar 的强引用,但 aVar 不持有对闭包的引用,因此不存在循环。

只是为了扩展您的问题,如果 aVar 强烈引用闭包,您 获得一个保留周期。例如:

func someFunc() {
    var aVar = SomeObj()
    aVar.funcWithClosure(something, completionHandler: {
        doSomethingWith(aVar)
    }
}

aVar 强引用闭包因为它调用函数,而闭包强引用 aVar 因为它在其主体中使用变量。要打破循环,您可以在闭包 之外创建对 aVar 的弱引用,如下所示:

func someFunc() {
    var aVar = SomeObj()
    weak var weakVar = aVar
    aVar.funcWithClosure(something, completionHandler: {
        if let weakVar = weakVar {
             doSomethingWith(weakVar)
        }
    }
}

weakVar 引用 aVar,所以你用它来代替 aVar。它弱引用它,所以当 aVar 超出范围时(当函数完成时),它的引用计数可以变为零。在闭包内部,由于 weakVar 是一个弱变量,需要在使用前以某种方式解包它。

在您的问题中,您建议将 [weak aVar] 添加到闭包的捕获列表中,我认为这行不通。

编辑:修复了将 weakVar 展开为 var,这是一个关键字。