-5

When I go back to look at some of Apple's Sprite Kit documentation I see a lot of occasions where a keyword called convenience comes up. For Example

convenience init(texture texture: SKTexture?, size size: CGSize)

What does it mean?

justinpawela
  • 1,968
  • 1
  • 14
  • 18
Stack Overflow
  • 149
  • 1
  • 1
  • 7
  • 2
    What is your question? – Hayley Guillou Jul 10 '15 at 02:02
  • 1
    Please put in some research effort before posting a question. This question (implicitly, what does the convenience keyword do?" is easily resolved by googling "convenience init swift". – Rikki Gibson Jul 10 '15 at 02:30
  • 1
    Possible duplicate of [Why convenience keyword is even needed in Swift?](https://stackoverflow.com/questions/30896231/why-convenience-keyword-is-even-needed-in-swift) – dandan78 Nov 24 '17 at 16:23

3 Answers3

1

That is a convenience initializer.

From the docs:

Convenience initializers are secondary, supporting initializers for a class. You can define a convenience initializer to call a designated initializer from the same class as the convenience initializer with some of the designated initializer’s parameters set to default values. You can also define a convenience initializer to create an instance of that class for a specific use case or input value type.

An initializer that is not marked convenience is a designated initializer:

Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.

The docs I linked above are very detailed, because there is a lot to initialization. You'll need to read them to really understand what's going on. But to give an example, let's say you create a car class:

class Car {

    let numberOfWheels: Int

    init(numberOfWheels: Int) {
        self.numberOfWheels = numberOfWheels
    }

    convenience init() {
        self.init(numberOfWheels: 4)
    }

}

The car class contains two initializers - a designated initializer and a convenience initializer.

The designated initializer is simply marked init. Inside a designated initializer, you are required to set all class properties so that the class is ready to go once initialization finishes. We set numberOfWheels inside our initializer.

The convenience initializer is marked convenience init. A convenience initializer may do whatever, but it must call one of the designated initializers before it finishes. In our example, it calls self.init(numberOfWheels: Int) and supplies a default number of wheels (4).

Convenience initializers are there exactly for their namesake: convenience. They allow you to set up initializers to classes that deal with common initialization cases. In our Car class, it is typical for a car to have four wheels, so our convenience initializer makes that common case easier.

To create a car, we can use either the designated initializer or the convenience initializer:

let carA = Car(numberOfWheels: 3)  // makes a car with 3 wheels
let carB = Car()                   // makes a car with 4 wheels

There are a lot more rules around initialization, especially in class hierarchies where super.init and initializer inheritance must be considered as well. I cannot describe them all any better or more succinctly than the official documentation, so again, I suggest you check there.

justinpawela
  • 1,968
  • 1
  • 14
  • 18
  • That really confused me – Stack Overflow Jul 10 '15 at 02:04
  • 1
    I added an example to try to help, but really you need to read the Initialization docs that I linked. – justinpawela Jul 10 '15 at 02:25
  • so if we have `convenience init` what method will being called first? `convenience init` or `init` ? – TomSawyer Mar 31 '16 at 10:38
  • @TomSawyer Whichever initializer you call will be called first! :) If you call an `init` method, than no `convenience init` methods will be called at all. However, if you call a `convenience init`, it will *always* end up calling one of the non-`convenience init` methods as part of its setup. A convenience initializer always calls thru to a designated initializer, but a designated initializer never calls a convenience initializer. Hope that helps. – justinpawela Mar 31 '16 at 15:14
1

Convenience initialisers allow you to initialise a class without all the required parameters the designated initialiser needs.

For example, in a very basic example you may have a designated initialiser for a class that requires a String:

init someName(value: String) {

You could also create a convenience initialiser to go along side this that takes an int and converts it to a String and then calls the designated initialiser and passes it that String. This way if your class is initialised and passed an int instead or by mistake, it won't error and will handle it.

convenience init someName2(value: Int) {
    let someString = String(value)
    someName(value: someString)
}

Another use for them is that the designated initialiser may take multiple parameters. You could create a convenience initialiser to go along side this that takes only one of those parameters, creates the others and sets them to some default values and then calls the designated initialiser, passing them all in. This way you do not need to specify all required parameters of the designated initialiser since if you don't, your convenience initialiser will fill in missing ones with default values.

convenience init someName(value: String) {
    someName(value: someString, value2: "DefaultValue")
}

init someName(value: String, value2: String) {
myles
  • 1,681
  • 1
  • 15
  • 27
1

Default init: Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.

convenience init: Convenience initializers are secondary, supporting initializers for a class. You can define a convenience initializer to call a designated initializer from the same class as the convenience initializer with some of the designated initializer’s parameters set to default values. You can also define a convenience initializer to create an instance of that class for a specific use case or input value type.

as per the Swift Documentation

Actually - Swift defines two kinds of initializers.

  • Designated initializers
  • Convenience initializers

Designated initializers are the primary initializers for a class. Every class should have at least one designated initializer.

init(parameters if any) {
}

Convenience initializers are secondary, supporting initializers for a class. Convenience initializers are written in the same style, but with the convenience modifier placed before the init keyword, separated by a space:

convenience init(parameters if any) {
}

Convenience init initializes the designated init method by calling self.init.

Example:

class HumanBeing {
var name: String
init(name: String) {
self.name = name
}

convenience init() {
self.init(name: “not set”)
// Convenience init call the designated init method
}
}
let humanBeingObj1 = HumanBeing() // calls convenience init
let humanBeingObj2 = HumanBeing(name: “abhilash”) // calls designated init