gpt4 book ai didi

ios - 我们是否应该继续在 iOS 中显式地将变量捕获为弱变量

转载 作者:行者123 更新时间:2023-12-01 15:27:33 25 4
gpt4 key购买 nike

假设我们有一个闭包链,像这样:

var myOtherVc: UIViewController! // get it somehow
self.dismiss(animated: true, completion: { [weak myOtherVc] in
myOtherVc?.present(sthElse, animated: true, completion: { [weak myOtherVc] in // <-- HERE
})
})

我的问题是我们是否捕获了变量 myOtherVc在最上面的块中为 weak我们应该继续明确所有子块中的弱点,还是编译器足够聪明以告诉 ARC 不保留?

更新

我想我需要澄清一下,如果块正在逃逸怎么办?
此外,我确实关心延迟释放。这就是为我使用弱点的全部意义。
public func doWhatever(_ success: @escaping () -> Void) { 
// do whatever
})

var myOtherVc: UIViewController! // get it somehow
self.dismiss(animated: true, completion: { [weak myOtherVc] in
SomeClass.doWhatever({ [weak myOtherVc] in // <-- HERE
myOtherVc?.present(sthElse, animated: true, completion: { [weak myOtherVc] in // <-- and HERE, too
})
})
})

最佳答案

我们假设所有的闭包都在逃逸,所以我做了这个操场,我得出的结论是你必须捕获你的 variableweak在使用您的 variable 的最新关闭中它不会从父或顶部闭包推断其引用类型:

typealias Closure = () -> Void
class A {
var closureA : Closure?

func runClosureA(closure: @escaping Closure) {
self.closureA = closure
closureA?()
}

func print() {
debugPrint("A is here!")
}

deinit {
debugPrint("A deinited")
}
}

另一个对链式闭包进行操作的类:
class B {


func runClosureB(closure: @escaping Closure) {
closure()
}

func operate() {
let a : A = A()
runClosureB { [weak a] in
a?.runClosureA { [a] in
a?.print()
}
}
}

deinit {
debugPrint("B deinited")
}
}

代码是:
var b: B? = B()
b?.operate()
b = nil

它将打印:
// "A is here!"
// "B deinited"

但是通过改变 operate功能:
func operate() {
let a : A = A()
runClosureB { [a] in
a.runClosureA { [weak a] in
a?.print()
}
}
}

结果会变成这样:
"A is here!"
"A deinited"
"B deinited"

更新:class A我做了一个 strong reference关闭为 closureA ,如果不创建引用,则不需要捕获 selfweak在关闭。

实际上,这取决于您使用的是哪个闭包以及它们之间的关系以及是否可以保留循环,因此您应该考虑将正确的闭包捕获为弱闭包。

关于ios - 我们是否应该继续在 iOS 中显式地将变量捕获为弱变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61906396/

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