【问题标题】:swift retain cycle in function函数中的快速保留周期
【发布时间】:2016-03-17 10:31:34
【问题描述】:

我想问一下这种情况下是否会发生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
    })
}

【问题讨论】:

    标签: swift function cycle retain


    【解决方案1】:

    不,它没有。闭包持有对aVar 的强引用,但aVar 不持有对闭包的引用,因此没有循环。

    【讨论】:

    • 谢谢,奥莱。所以如果我加[weak aVar],还是没有错?只是重复。对吗?
    • 不,你通常不能这么说。在您的特定代码示例中,它可能会起作用,因为您没有对分配给aVar 的对象做任何事情。但是您的代码示例无论如何都没有多大意义。当一个对象不存在强引用时,它会被释放,所以无论你是否使用weak,都会有很大的不同。
    【解决方案2】:

    只是为了扩展您的问题,如果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,这是一个关键字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 2018-05-13
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 2020-09-23
      • 2018-11-15
      相关资源
      最近更新 更多