gpt4 book ai didi

swift - 带有计时器类的 UIView 可以防止 deinit

转载 作者:行者123 更新时间:2023-11-30 11:36:36 28 4
gpt4 key购买 nike

我不确定这是否是最好的设计设置,但我现在有这样的东西:

class MyView: UIView {

var nextView: NextView?

override func layoutSubviews() {
super.layoutSubviews()
nextView = NextView()
nextView!.go()
}

deinit {
print("call me")
}

}

class NextView {

var timer: Timer?

func go() {
timer = Timer.scheduledTimer(withTimeInterval: 1,
repeats: true,
block: { [weak self] _ in })
}

deinit {
print("call me")
timer?.invalidate()
timer = nil
}
}

通过此设置,在 UIViewController 从根 UIViewController 更改后,MyView 和 NextView 不会取消初始化。如果我将 var nextView 更改为弱 var nextView,则会调用反初始化器,但在类加载后 nextView 为零。函数 go() 不会被调用。

当 MyView 所在的 UIViewController 取消初始化并取消初始化时,如何取消初始化这两个类?

最佳答案

你的NextView的原因没有被取消初始化是因为,在此设置中,MyView拥有对 NextView 的强引用(且仅有一个) 。如果你把它设为weak引用,然后NextView不被任何强引用保留并立即取消初始化。

内存在经典 UI 层次结构中的工作方式如下 - View 对其每个 subview 拥有强引用,对其父 View 拥有弱引用。这可以防止保留循环,同时允许删除 View 以“级联”其所有 subview 的反初始化。

默认情况下,使用方法 addSubview自动创建这个强引用,如 documentation 中所写。 .

This method establishes a strong reference to view and sets its next responder to the receiver, which is its new superview.

因此,在您的情况下,最好的方法可能是使用 MyView 中的以下内容更新您的代码

override func layoutSubviews() {
super.layoutSubviews()
nextView = NextView()
addSubview(nextView)
nextView!.go()
}

希望有帮助!

<小时/>

我不想对代码本身发表太​​多评论,因为这不是主题,但我很确定在layoutSubviews 中创建 subview 是一个糟糕的主意。

此外,在您的情况下,您每次都将重新创建此 View ,这可能会导致计算成本高昂。如果您只想创建一次,请使用

override func layoutSubviews() {
super.layoutSubviews()

if nextView == nil {
nextView = NextView()
addSubview(nextView)
nextView!.go()
}
}

关于swift - 带有计时器类的 UIView 可以防止 deinit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49698734/

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