繁体   English   中英

在Swift中将一个默认属性值传递给另一个

[英]Passing one default property value to another in Swift

想象一下我想做以下事情。 我有一个带有几个属性的UIView的自定义子类。 我想从另一个先前的属性中初始化其中一个属性。

class MyView :UIView {

    var driver = HumanDriver()

    var car = Car(driver: driver)
    var plane = Plane(driver: driver)
    var train = Train(driver: driver)
    var spaceship = Spaceship(driver: driver)

    override init() {
        super.init()
    }
    required init(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
}

此代码将显示错误: 'MyView.Type' does not have a member named 'driver' 因此,解决此问题的一个显而易见的尝试是在初始化程序中定义默认值。 如果只有一个初始化程序,这很好。 但是,如果我们有几个呢? 好吧,我可以尝试在单个设置功能中收集通用代码,如下所示:

class MyView :UIView {

    var driver = HumanDriver()

    var car
    var plane
    var train
    var spaceship

    override init() {
        setupMyView()
        super.init()
    }
    required init(coder aDecoder: NSCoder) {
        setupMyView()
        super.init(coder:aDecoder)
    }
    override init(frame: CGRect) {
        setupMyView()
        super.init(frame: frame)
    }

    func setupMyView() {
        car = Car(driver: driver)
        plane = Plane(driver: driver)
        train = Train(driver: driver)
        spaceship = Spaceship(driver: driver)
    }

}

但是,这也会引起错误,这一次: 'self' used before super.init call 这是可以理解的,因为在调用init之前我们正在使用self。

有什么好的解决方案吗? 显然,我可以使用隐式解包的可选参数,但似乎应该有更好的方法!

如何覆盖驱动程序设置程序并在其中设置属性? 像这样:

class MyView :UIView {

    var driver:HumanDriver = HumanDriver() {
        didSet{
            car = Car(driver: driver)
            plane = Plane(driver: driver)
            train = Train(driver: driver)
            spaceship = Spaceship(driver: driver)
        }
    }

    var car: Car?
    var plane: Plane?
    var train: Train?
    var spaceship: Spaceship?
}

这样,您将保持整洁的初始化程序。 顺便说一句,您可能至少需要添加所需的初始化程序,但这就是其他内容。 我认为这是您可能想要得到的最干净的解决方案之一。

希望这可以帮助。

答案在这里: https : //stackoverflow.com/a/26772103/1025041确实是我在寻找的东西,尽管对于要实现的目标确实是很多样板! 希望苹果公司在将来使此变得更容易。

供参考,这是该方法适用于我的示例的方式:

extension UIView {
    enum InitMethod {
        case Default
        case Coder(NSCoder)
        case Frame(CGRect)
    }
}

class MyView: UIView {

    var driver = HumanDriver()

    var car
    var plane
    var train
    var spaceship

    override convenience init() {
        self.init(.Default)
    }

    override convenience init(frame: CGRect) {
        self.init(.Frame(frame))
    }

    required convenience init(coder aDecoder: NSCoder) {
        self.init(.Coder(aDecoder))
    }

    private init(_ initMethod: InitMethod) {

        car = Car(driver: driver)
        plane = Plane(driver: driver)
        train = Train(driver: driver)
        spaceship = Spaceship(driver: driver)

        switch initMethod {
            case .Default: super.init()
            case let .Coder(coder): super.init(coder: coder)
            case let .Frame(frame): super.init(frame: frame)
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM