init позволяет свойства со ссылкой на себя в подклассе в Swift - PullRequest
0 голосов
/ 28 мая 2019

Я быстро учусь и очень часто сталкиваюсь со следующей проблемой.У меня будет класс со свойством, которое выглядит так, как будто оно должно быть let, поскольку оно будет установлено только один раз.Я также хотел бы, чтобы этот дочерний объект поддерживал ссылку на своего владельца, который также должен быть свойством let, так как родительские отношения не изменятся.Проблема возникает, когда родительский класс подклассов другого класса и все свойства let должны быть установлены до запуска super.init (), но для инициализации требуется ссылка на self.

Вот краткий пример

class NodeView: UIView {
    let _nodePlugView: NodePlugView

    init (node: Node) {
        _nodePlugView = NodePlugView (parentView: self)
        super.init ()
    }
}

Конечно, я мог бы просто использовать var для этих _nodePlugView, но это не совсем правильно.Есть ли другая модель, которую люди рекомендуют?

Ответы [ 2 ]

2 голосов
/ 28 мая 2019

Это хороший вариант использования для неявно развернутого необязательного параметра.

Документация Apple гласит:

«Неявно развернутые дополнительные параметры полезны, когда дополнительныезначение подтверждается как существующее сразу после того, как опциональное значение впервые определено, и определенно можно предположить, что оно существует в каждой точке после этого.Основное использование неявно развернутых необязательных опций в Swift - во время инициализации класса. ”

Это означает, что вы можете использовать неявно развернутый необязательный необязательный параметр, когда свойство зависит от некоторого аспекта себя (но не суперкласса), когдаоно инициализируется.

Свойство будет иметь значение nil до тех пор, пока оно не будет установлено в методе init(), а затем никогда не должно иметь значение nil.

class NodeView: UIView {

    var _nodePlugView: NodePlugView!

    init (node: Node) {
        super.init()
        _nodePlugView = NodePlugView (parentView: self)
    }
}
1 голос
/ 28 мая 2019

Вы можете использовать переменную lazy.

lazy var _nodePlugView: NodePlugView = NodePlugView(parentView: self)

Ленивые переменные инициализируются после инициализации самого объекта.

Если вам действительно нужно, чтобы это была постоянная let, альтернативой может быть использование инициализатора для NodePlugView, который не принимает параметр parentView, и метода для установки parentView после его инициализации.

let _nodePlugView: NodePlugView

init (node: Node) {
    _nodePlugView = NodePlugView()
    super.init()
    _nodePlugView.setParentView(self)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...