为什么在 UIView 再次添加到父级之前不调用 deinit?
Why is deinit not called until UIView is added to parent again?
我有一个要添加到 UIViewController 的 UIView,并且通常会测试取消初始化以确保我做的事情是正确的。但是当我没有将 viewController 中的变量设置为 nil 并且只使用 .removeFromSuperView() 时,在我再次添加 UIView 然后调用它之前,不会调用 UIView 中的 deinit() 方法。但是,如果我使用 removeFromSuperView() 并将变量设置为 nil,则会立即调用 deinit()。这是为什么?
这是 UIView() class:
class TestView: UIView {
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
print("init is happneing")
}
deinit {
print("de init is happneing")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这是父级 ViewController:
class MyViewController: UIViewController {
var tstview : TestView?
//adding the UIView by tapping on a button
@IBAction func addView(_ sender: UIButton) {
let test = TestView()
tstview = test
tstview?.frame = CGRect(x: 50, y: 60, width: self.view.frame.width-100, height: self.view.frame.height-200)
tstview?.backgroundColor = UIColor.white
self.view.addSubview(tstview!)
}
override func viewDidLoad() {
super.viewDidLoad()
}
//removing UIView by touching elsewhere
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
tstview?.removeFromSuperview()
// tstview = nil
}
}
deinit
在没有人引用该对象时调用。如果您没有将 tstview
设置为 nil
,您的 MyViewController 仍会引用它,因此不会调用 deinit
。当您调用 addView
时,语句 tstview = test
最终删除了对旧视图的最后一个引用,从而触发了析构程序。
您可以在 Swift documentation 中阅读更多关于取消初始化的概念。
如果您想在视图分离后立即收到通知,请改为override willMove(toSuperview:)
。
class TestView: UIView {
...
override func willMove(toSuperview newSuperview: UIView?) {
if newSuperview == nil {
print("removed from parent")
}
}
}
我有一个要添加到 UIViewController 的 UIView,并且通常会测试取消初始化以确保我做的事情是正确的。但是当我没有将 viewController 中的变量设置为 nil 并且只使用 .removeFromSuperView() 时,在我再次添加 UIView 然后调用它之前,不会调用 UIView 中的 deinit() 方法。但是,如果我使用 removeFromSuperView() 并将变量设置为 nil,则会立即调用 deinit()。这是为什么?
这是 UIView() class:
class TestView: UIView {
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
print("init is happneing")
}
deinit {
print("de init is happneing")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
这是父级 ViewController:
class MyViewController: UIViewController {
var tstview : TestView?
//adding the UIView by tapping on a button
@IBAction func addView(_ sender: UIButton) {
let test = TestView()
tstview = test
tstview?.frame = CGRect(x: 50, y: 60, width: self.view.frame.width-100, height: self.view.frame.height-200)
tstview?.backgroundColor = UIColor.white
self.view.addSubview(tstview!)
}
override func viewDidLoad() {
super.viewDidLoad()
}
//removing UIView by touching elsewhere
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
tstview?.removeFromSuperview()
// tstview = nil
}
}
deinit
在没有人引用该对象时调用。如果您没有将 tstview
设置为 nil
,您的 MyViewController 仍会引用它,因此不会调用 deinit
。当您调用 addView
时,语句 tstview = test
最终删除了对旧视图的最后一个引用,从而触发了析构程序。
您可以在 Swift documentation 中阅读更多关于取消初始化的概念。
如果您想在视图分离后立即收到通知,请改为override willMove(toSuperview:)
。
class TestView: UIView {
...
override func willMove(toSuperview newSuperview: UIView?) {
if newSuperview == nil {
print("removed from parent")
}
}
}