Установка translatesAutoresizingMaskIntoConstraints = false создает несколько объектов, которые мгновенно деинициализируются.

avatar
J. Doe
8 апреля 2018 в 12:04
94
1
0

Это мой код:

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
        }
    }

}

Обратите внимание на комментарий при изменении значения translatesAutoresizingMaskIntoConstraints с помощью кнопки. Изменение этого значения приведет к такому странному поведению.

Это мой журнал после добавления MyView в раскадровку в классе Test:

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 первый журнал печати исчезает. Почему изменение значения translatesAutoresizingMaskIntoConstraints мгновенно создает и обнуляет объект NextView?

Источник

Ответы (1)

avatar
nayem
8 апреля 2018 в 16:17
1

Хорошо, прежде всего вам нужно взглянуть на translatesAutoresizingMaskIntoConstraints документацию от Apple. Там написано:

По умолчанию для свойства установлено значение true для любого представления, которое вы создаете программно.

Теперь перейдем к вашему примеру.

Когда вы сказали commenting translatesAutoresizingMaskIntoConstraints off, это двусмысленно. Вы должны либо сказать комментарий/раскомментировать, либо использовать значение true/false. Думать было бы легче.

Рассмотрите эти два случая:

  1. translatesAutoresizingMaskIntoConstraints = true(по умолчанию при создании из кода) система предполагает, что вы сами обрабатываете кадрирование представления, и распространяет дополнительный проход на layoutSubviews() на случай, если вы нужно изменить рамку любого из ваших подвидов.

  2. translatesAutoresizingMaskIntoConstraints = false. Система узнает, что кадры ваших подпредставлений будут вычисляться динамически, и по этой причине вам не нужен шанс перестроить свои подпредставления. Таким образом, система не распространяет дополнительный проход на layoutSubviews()

  3. .

Теперь вам нужно знать, когда вызывается deinit. В самом простом случае, если какой-либо объект инициализируется второй раз, вызывается deinit первого объекта. Вы уже должны были получить ответ.

Поясню:

  • Когда вы использовали translatesAutoresizingMaskIntoConstraints = true (или если вы даже не использовали) ваш layoutSubviews() вызывается дважды. Как результат, который вы инициализировали NextView дважды. При инициализации NextView во второй раз вызывается deinit первого экземпляра.

  • Когда вы использовали translatesAutoresizingMaskIntoConstraints = false ваш layoutSubviews() вызывается один раз. Следовательно, deinit не получает звонил.