Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Overload init()

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

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
}
like image 408
Zeropointer Avatar asked Oct 07 '14 10:10

Zeropointer


People also ask

What does init () do in Swift?

Swift init() Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.

Can we override init in Swift?

Override initializer In Swift initializers are not inherited for subclasses by default. If you want to provide the same initializer for a subclass that the parent class already has, you have to use the override keyword.

What does super init do in Swift?

The init() initializer for Bicycle starts by calling super. init(), which calls the default initializer for the Bicycle class's superclass, Vehicle. This ensures that the numberOfWheels inherited property is initialized by Vehicle before Bicycle has the opportunity to modify the property. After calling super.


1 Answers

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 title and imageName were both var and 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.


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.init must 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).

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

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:

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.


UPDATE 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.

like image 98
Jeffery Thomas Avatar answered Oct 24 '22 18:10

Jeffery Thomas