设置translatesAutoresizingMaskIntoConstraints = false会创建立即取消初始化的多个对象

时间:2018-04-08 12:04:00

标签: swift

这是我的代码:

import UIKit

class MyView: UIView {

    var nextView: NextView?

    private var button: UIButton! = UIButton()

    init(){
        super.init(frame: CGRect.zero)
        commonLoad()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonLoad()
    }

    private func commonLoad() {
        addSubview(button)
        button.translatesAutoresizingMaskIntoConstraints = false //comment this on and off to see the change
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        nextView = NextView(view: self)
    }

    deinit {
        print("deinit my view")
    }

}

class NextView {
    private weak var view: UIView?

    init(view: UIView){
        self.view = view
        guard let v = self.view else { fatalError() }
        let anotherSubView = UIView()
        v.addSubview(anotherSubView)
    }


    deinit {
        print("Deinit next view")
    }
}

class Test: UIViewController{

    override func viewDidAppear(_ animated: Bool) {
        Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
            let storyBoard = UIStoryboard(name: "Main", bundle:nil)
            let nextViewController = storyBoard.instantiateViewController(withIdentifier: "otherVC") as! otherVC
            UIApplication.shared.keyWindow?.rootViewController = nextViewController
        }
    }

}

从buttn更改translatesAutoresizingMaskIntoConstraints的值时请注意注释。改变这个值会产生这种奇怪的行为。

这是我在Test类中添加MyView到故事板后的日志:

Deinit next view //<-- Instant called, WHY?!
deinit my view //<-- after 1 second, good
Deinit next view //<-- after 1 second, good, but why did it created another object of NextView?

当关闭translatesAutoresizingMaskIntoConstraints时,第一个printlog消失。为什么更改translatesAutoresizingMaskIntoConstraints的值会立即创建并忽略对象NextView?

1 个答案:

答案 0 :(得分:1)

好的,首先您需要查看Apple的translatesAutoresizingMaskIntoConstraints文档。它说:

  

默认情况下,对于您以编程方式创建的任何视图,该属性都设置为 true

现在来看你的榜样。

当你说 评论翻译关闭来自时,它是不明确的。您应该说注释/取消注释或使用true / false的值。这会更容易思考。

考虑以下两种情况:

  1. translatesAutoresizingMaskIntoConstraints = true (默认情况下,从代码创建时),系统假定您自己正在处理视图的框架并将额外的传递传播到{{1如果您需要更改任何子视图的框架。

  2. <强> layoutSubviews() 即可。系统会知道您的子视图将动态计算帧,因此您不需要任何机会重新构建子视图。因此,系统不会将任何额外的传递传播到translatesAutoresizingMaskIntoConstraints = false

  3. 现在您需要知道何时调用layoutSubviews()。对于最简单的情况,如果任何对象初始化第二时间,则第一个对象的deinit被调用。你现在应该得到答案。

    让我告诉你:

    • 使用deinit时(或 如果您甚至没有使用),您的translatesAutoresizingMaskIntoConstraints = true会被调用两次。作为一个 结果您初始化layoutSubviews()两次。初始化时 第二次NextView,第一个实例的NextView被调用。

    • 使用deinit时 您的translatesAutoresizingMaskIntoConstraints = false被调用一次。因此没有layoutSubviews()得到 调用。