如何使用共享init方法初始化let变量?

时间:2015-03-17 23:55:59

标签: ios swift

我想使用let设置一个变量,这样它不是可选的,不会随着时间的推移而改变,并且每次都不需要杂乱的解包。我知道我可以合法地设置它,但只能在其中一个init方法中。问题是Swift要求您覆盖init(coder aDecoder: NSCoder)初始值设定项。但是我从来没有一个应用程序曾经调用过初始化程序。它始终是被调用的init(frame: CGRect)初始值设定项。因此,如果我不必覆盖init(coder aDecoder: NSCoder),那么我只需执行self.imageView = UIImageView.new()中的init(frame: CGRect)即可完成,但编译器会抱怨其未设置在另一个中init也是。我尝试使用从两个inits调用的sharedInit()方法,但编译器不允许我从那里设置imageView,因为它只在init方法之外读取。如果不在init方法中直接执行所有init两次,你应该怎么做呢?

class SuperCoolView : UIView {

    let imageView: UIImageView

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

    override init(frame: CGRect) {
        sharedInit()
        super.init(frame: frame)
    }

    func sharedInit() {
        self.imageView = UIImageView.new()
        // Other similar shared init
    }

}

2 个答案:

答案 0 :(得分:2)

只需使用延迟初始化和私有'set'的组合来获取:

class SuperCoolView : UIView {
  public private(set) lazy var imageView: UIImageView = {
    // In practice, do more here.  Access state in this instance.
    // Or, include more computation.
    UIImageView.new()
  }()

  // inits w/o setting imageView
}

'私人套装'使其外部与let相同; lazy允许您根据SuperCoolView实例中的其他状态初始化值。

请注意,如果imageView和其他的初始化不依赖于实例中的状态,那么您可以避免使用lazy并从闭包中进行初始化。

答案 1 :(得分:2)

我发现this answer并且喜欢它的方法。它修复了问题,并且更加清洁恕我直言。通过实现init(coder aDecoder: NSCoder)通常我们会保持这样的外观,即当它不能时,可以从笔尖/故事板初始化该视图。

class SuperCoolView : UIView {

let imageView: UIImageView

required init(coder aDecoder: NSCoder) {
    fatalError("NSCoding not supported")
}

override init(frame: CGRect) {
    self.imageView = UIImageView.new()
    // Other stuff
    super.init(frame: frame)
}

}