init快速让子类中引用self的属性

时间:2019-05-27 21:55:46

标签: swift

我学习迅速,经常遇到以下问题。我将拥有一个带有属性的类,该属性似乎应该是let属性,因为它只会被设置一次。我还希望该子对象保留对其所有者的引用,该引用也应该是let属性,因为父级关系不会改变。当父类继承另一个类并且在运行let之前需要设置所有super.init ()属性,但需要引用self来初始化时,会出现问题。

这是一个简单的例子

class NodeView: UIView {
    let _nodePlugView: NodePlugView

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

当然,我可以仅将var用于这些_nodePlugView,但感觉并不正确。人们会推荐另一种模式吗?

2 个答案:

答案 0 :(得分:2)

这是一个很好的用例,它隐式地解开了可选的内容。

苹果documentation指出:

  

“当可选值是   确认在第一次定义可选项后立即存在,并且   可以肯定地认为此后的每个时刻都存在。的   在上课期间,Swift中隐式解开的Optionals的主要用法是   初始化。”

这意味着当属性在初始化时依赖于self(而不是超类)的某些方面时,可以使用隐式解包的可选内容。

该属性将一直为nil,直到在init()方法中对其进行设置为止,然后再也不能为nil。

class NodeView: UIView {

    var _nodePlugView: NodePlugView!

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

答案 1 :(得分:1)

您可以使用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)
}