Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在Swift中将一个默认属性值传递给另一个_Ios_Xcode_Swift_Xcode6 - Fatal编程技术网

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

Ios 在Swift中将一个默认属性值传递给另一个,ios,xcode,swift,xcode6,Ios,Xcode,Swift,Xcode6,想象一下,我想做如下的事情。我有一个自定义的UIView子类,它有几个属性。我想从另一个先前属性初始化其中一个属性 class MyView :UIView { var driver = HumanDriver() var car = Car(driver: driver) var plane = Plane(driver: driver) var train = Train(driver: driver) var spaceship = Spaces

想象一下,我想做如下的事情。我有一个自定义的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”没有名为“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)
    }

}
但这也会导致一个错误,这一次:
在super.init调用之前使用的“self”
。这是可以理解的,因为我们在调用init之前使用self


有什么好的解决办法吗?显然,我可以使用隐式展开选项,但似乎应该有更好的方法

重写驱动程序setter并在其中设置属性如何?大概是这样的:

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?
}
这样,您将保持初始值设定项的整洁。顺便说一句,您可能需要添加至少所需的初始值设定项,但这是另一回事。我认为这是你可能想要的最干净的解决方案之一

希望这能有所帮助。

这里的答案是:这确实是我一直在寻找的,尽管这确实是一个关于我正在努力实现的目标的样板文件!让我们希望苹果在未来能让这变得更容易

作为参考,以下是该方法如何应用于我的示例:

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)
        }
    }
}

为什么要编写init和init(frame:)这两个方法??也是coder??事实上,我认为在初始化“driver”的值时不会调用didSet,所以这不起作用。