gpt4 book ai didi

swift - 传递方法而不是闭包时会发生保留循环

转载 作者:搜寻专家 更新时间:2023-11-01 06:06:12 27 4
gpt4 key购买 nike

在 Swift 中,我们可以使用 ObjC 中没有的出色功能:可以在任何需要使用闭包的地方使用方法。但它会导致保留循环。看这个例子:

import Foundation

class C1 {
let closure: Void -> Void
init(closure: Void -> Void) {
self.closure = closure
}

deinit {
print("C1 deinit")
}
}

class C2 {
var c1: C1!

func initializeC1() {
c1 = C1(closure: f)
}

func f() {}

deinit {
print("C2 deinit")
}
}

func main() {
let c2 = C2()
c2.initializeC1()
}

main()

这里我们创建了循环 C2 -> C1 -> f -> C2。如果你运行这个程序,deinit 将不会被调用。但是,如果您将 initializeC1 中的 f 替换为 {},例如,它将是。

对于常规闭包,我们可以使用捕获列表来避免强保留,但看起来您不能将它们用于方法。所以,问题是:在这种情况下我们如何打破保留周期,这有可能吗?

最佳答案

当然,我们可以像这样通过将绑定(bind)方法包装在闭包中来“弱化”绑定(bind)方法:

import Foundation

class C1 {
let closure: Void -> Void
init(closure: Void -> Void) {
self.closure = closure
}

deinit {
print("C1 deinit")
}
}

class C2 {
var c1: C1!

func initializeC1() {
// HERE we wrap a method call into a closure to break retain-cycle.
c1 = C1(closure: { [weak weakSelf = self] in
weakSelf?.f()
})
}

func f() {}

deinit {
print("C2 deinit")
}
}

func main() {
let c2 = C2()
c2.initializeC1()
}

main()
//C2 deinit
//C1 deinit

关于swift - 传递方法而不是闭包时会发生保留循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36764101/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com