11

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
}
Zeropointer
  • 510
  • 2
  • 7
  • 24
  • What does not't work exactly? What errors are you getting? I guess you need to provide values for any new properties introduced by the class. And then call `super.init()` – Kirsteins Oct 07 '14 at 10:55

1 Answers1

22

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.

Community
  • 1
  • 1
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • Thanks that works when i have more overloaded init i must write allways convenience 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 } – Zeropointer Oct 07 '14 at 11:28
  • There are two kinds of initializers: designated and convenience. If at all possible, you want to only have 1 designated initializer, all others should be convenience initializers (see: [Designated Initializers and Convenience Initializers](https://developer.apple.com/library/prerelease/iOS/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-XID_325)). – Jeffery Thomas Oct 07 '14 at 12:34
  • Fail, this does nothing – CommaToast Nov 17 '15 at 09:52
  • @JefferyThomas could you please provide a link to the Apple's advice where is mentioned that there should be only one designated initializer? This claim doesn't sound right to me. Thanks – 0101 Jul 15 '16 at 19:12
  • @0101 I cited my source. – Jeffery Thomas Jul 16 '16 at 01:46
  • @JefferyThomas thank you. In quotations above is however not mentioned that there can be / should be **only one** designated initializer. The quotations are also rather obj-c oriented. If you look at Swift 2.2 docs (Designated Initializers and Convenience Initializers) you'll see "*Every class must have at least one designated initializer.*" and "*Classes tend to have very few designated initializers, and it is quite common for a class to have only one*"... – 0101 Jul 16 '16 at 13:08
  • 1
    @0101 Apple clearly intends programmers to use the fewest possible designated initializers, one being the ideal number. In the reference I cited, it is assumed there would be only one. In the reference you cited, they state, "it is quite common for a class to have only one". Given all this, I think it's fair to say, a class should only have one designated initializer, unless you have a good reason for more. – Jeffery Thomas Jul 16 '16 at 18:24