xcode Swift 重载 init()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26234129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:48:04  来源:igfitidea点击:

Swift Overload init()

xcodeswiftoverloadinginit

提问by Zeropointer

i will overload the init Method in Swift how i can implement that?

我将在 Swift 中重载 init 方法,我该如何实现呢?

here my code that not work

这里我的代码不起作用

code removed

代码已删除

Edit:

编辑:

So it would be work fine

所以它会工作得很好

override init() {
    super.init();
}

init(title:String?) {
    super.init();
    self.title = title
}

convenience init(title:String?, imageName:String?) {
    self.init(title:title)
    self.imageName = imageName
}

convenience init(title:String?, imageName:String?, contentKey:String?) {
    self.init(title:title, imageName:imageName)
    self.contentKey = contentKey
}

回答by Jeffery Thomas

Updated Answer

更新答案

class Y { }
class X : Y {
    var title: String?
    var imageName: String?

    convenience override init() {
        self.init(title: nil, imageName: nil)
    }

    convenience init(title:String?) {
        self.init(title: title, imageName: nil)
    }

    init(title: String?, imageName: String?) {
        self.title = title
        self.imageName = imageName
        super.init()
    }
}
  • Use the most complete initializer as the designated initializer.

    In this case init(title: String?, imageName: String?)is the only initializer that sets all its properties, so it should be the designated initializer.

  • Initialize your properties before calling super.init().

    My old answer only worked because titleand imageNamewere both varand optional.

    In Two-Phase Initialization section of The Swift Programming Language: Initialization

    Safety check 1

    A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.

  • 使用最完整的构造器作为指定构造器。

    在这种情况下init(title: String?, imageName: String?)是唯一设置其所有属性的初始化程序,因此它应该是指定的初始化程序。

  • 在调用之前初始化您的属性super.init()

    我的旧答案仅有效,因为title并且imageName两者都是var可选的。

    The Swift Programming Language: Initialization 的两阶段初始化部分

    安全检查 1

    一个指定的初始化器必须确保它的类引入的所有属性在它委托给一个超类初始化器之前都被初始化。



Old Answer

旧答案

I plugged the sample into a playground, here is how I got it to work:

我将样本插入操场,这是我如何让它工作:

class Y { }
class X : Y {
    var title: String?
    var imageName: String?

    override init() {

    }

    init(aTitle:String?) {
        super.init()
        self.title = aTitle
    }

    convenience init(aTitle:String?, aImageName:String?) {
        self.init(aTitle: aTitle)
        self.imageName = aImageName
    }
}
  • init(aTitle:String?, aImageName:String?)cannot call init(aTitle:)and still be a designated initializer, it must be a convenience initializer.
  • self.initmust be before anything else in init(aTitle:String?, aImageName:String?).
  • initializer must be passed the parameter name self.init(aTitle)must be self.init(aTitle: aTitle).
  • init(aTitle:String?, aImageName:String?)不能调用init(aTitle:)并且仍然是一个指定的构造器,它必须是一个便利构造器。
  • self.init必须在init(aTitle:String?, aImageName:String?).
  • 必须传递初始值设定项,参数名称self.init(aTitle)必须是self.init(aTitle: aTitle).

As a side note, I removed the unneeded semicolons and put super.init()first for style reasons.

作为旁注,我删除了不需要的分号,并super.init()出于风格原因将其放在首位。

Hope that helps.

希望有帮助。



UPDATE

更新

To follow Apple's advice, there should only be one designated, the rest should be convenience initializers. For example, if you decide init(aTitle:String?)should be the designated initializer, then the code should look like:

按照 Apple 的建议,应该只指定一个,其余的应该是便利初始化程序。例如,如果您决定init(aTitle:String?)应该指定初始化程序,那么代码应该如下所示:

convenience override init() {
    self.init(aTitle: nil) // A convenience initializer calls the designated initializer.
}

init(aTitle:String?) {
    super.init() // Only the designated initializer calls super.init.
    self.title = aTitle
}

convenience init(aTitle:String?, aImageName:String?) {
    self.init(aTitle: aTitle)  // A convenience initializer calls the designated initializer.
    self.imageName = aImageName
}

There are times when you might want more than once designated initializer, for example, UIView, but that should be an exception, not the rule.

有时您可能需要多次指定初始化程序,例如,UIView,但这应该是一个例外,而不是规则。



UPDATE 2

更新 2

Classes should have one designated initializer. Convenience initializer will (eventually) call the the designated initializer.

类应该有一个指定的初始化程序。便利初始化程序将(最终)调用指定的初始化程序。

Initialization

初始化

A class may have multiple initializers. This occurs when the initialization data can take varied forms or where certain initializers, as a matter of convenience, supply default values. In this case, one of the initialization methods is called the designated initializer, which takes the full complement of initialization parameters.

一个类可能有多个初始化器。当初始化数据可以采用不同的形式或者某些初始化器为了方便起见提供默认值时,就会发生这种情况。在这种情况下,其中一种初始化方法称为指定初始化程序,它采用初始化参数的完整补充。

Multiple initializers

多个初始化器

The Designated Initializer

The initializer of a class that takes the full complement of initialization parameters is usually the designated initializer. The designated initializer of a subclass must invoke the designated initializer of its superclass by sending a message to super. The convenience (or secondary) initializers—which can include init—do not call super.Instead they call (through a message to self) the initializer in the series with the next most parameters, supplying a default value for the parameter not passed into it. The final initializer in this series is the designated initializer.

指定的初始化程序

采用完整初始化参数的类的初始化程序通常是指定的初始化程序。子类的指定初始化程序必须通过向 super 发送消息来调用其超类的指定初始化程序。便利(或辅助)初始值设定项(可以包括 init)不调用 super。相反,他们调用(通过给 self 的消息)系列中具有次多参数的初始化程序,为未传递给它的参数提供默认值。本系列的最后一个初始化器是指定初始化器。