在UIView的超类初始化之后初始化它



在这里查看斯坦福iOS 9课程中的一张讲座幻灯片,他正在创建一个新的UIView,其中有两个初始化器(一个是从故事板创建的UIView,另一个是在代码中创建的(。以下代码写在该特定幻灯片的底部:

    func setup() {....}  //This contains the initialization code for the newly created UIView
    override init(frame: CGRect) {  //Initializer if the UIView was created using code.
        super.init(frame: frame)
        setup()
    }
    required init(coder aDecoder: NSCoder) {  //Initializer if UIView was created in storyboard
        super.init(coder:aDecoder)
        setup()
    }

规则是,在从超类获取init之前,必须首先初始化所有自己的属性。那么,为什么在这种情况下,他在初始化自己的setup()之前调用他的超类init super.init呢?这不是与以下规则相矛盾吗:

安全检查1指定的初始化器必须确保其类引入的所有属性都已初始化,然后才能委托给超类初始化器。

如上所述,对象的内存只有在其所有存储属性的初始状态已知后才被视为完全初始化。为了满足此规则,指定的初始值设定项必须确保在向上传递链之前,它自己的所有属性都已初始化。

我还没有看到这个例子中的所有其他代码,但规则只是在调用super.init()之前必须初始化属性(即,它们占用的内存必须设置为某个初始值(,而不是不能运行额外的设置代码。

您甚至可以通过声明属性lazy var或使用自动初始化为nilvar选项来避免真正初始化属性。然后,您可以在呼叫super.init()后设置它们。

例如:

class Foo: UIView {
    var someSubview: UIView!  // initializes automatically to nil
    lazy var initialBackgroundColor: UIColor? = {
        return self.someSubview.backgroundColor
    }()
    init() {
        super.init(frame: .zero)
        setup()          // do some other stuff
    }
    func setup() {
        someSubview = UIView()
        someSubview.backgroundColor = UIColor.whiteColor()
        addSubview(someSubview)
    }
}

最新更新