16

I saw in this answer that the user specifies a convenience required init(). What exactly does this mean?

I understand that the required keyword is used for overriding a superclass's designated initializer, but what does the convenience required declarative do?

Community
  • 1
  • 1
Doug Smith
  • 29,668
  • 57
  • 204
  • 388

3 Answers3

27

A convenience required initializer is an initializer that is enforced onto all subclasses but is not the designated initializer. This means that said initializer will eventually call a designated initializer in its initialization chain.

Designated Initialisers

A designated initialiser is the canonical initializer for a class and the one which all required and convenience initialisers should call. The Docs say:

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 Initialisers

A convenience initialiser is an initializer that sets up certain configuration information on a class...conveniently. Documentation:

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.

You do not have to provide convenience initializers if your class does not require them. Create convenience initializers whenever a shortcut to a common initialization pattern will save time or make initialization of the class clearer in intent

Required Initialisers

Required initializers can be thought of as a binding contract between a parents interface and subsequent subclasses. Its your means of enforcing that all your children are aware of and implement a certain set of initialisers.

Write the required modifier before the definition of a class initializer to indicate that every subclass of the class must implement that initializer:

Community
  • 1
  • 1
Daniel Galasko
  • 23,617
  • 8
  • 77
  • 97
  • 1
    Thanks for the outline of the three types, but what does it mean when you *combine* convenience and required into a `convenience required` init? – Doug Smith Nov 16 '14 at 18:54
  • 3
    It means (1) the initializer is not a designated initializer itself, and (2) subclasses are required to implement this initializer. – Greg Parker Nov 19 '14 at 07:25
  • 1
    @GregParker that being said it is an interest notion of making a convenience initialiser required. Its like a "nice to have" being something you "have to have" :) – Daniel Galasko Nov 19 '14 at 07:28
  • 1
    The `required` and `convenience` keywords are 100% independent of each other. Using them in combination doesn't change anything about the semantics of each keyword when considered independently. – nhgrif Feb 15 '17 at 19:43
1

Declaring required initialiser of class as convenience lets subclasses easily inherit it and thus ommit its implementation

protocol P {
    var some: Int! {get}
    init(some: Int)
}

class C: P {
    private(set) var some: Int!
    convenience required init(some: Int) {
        self.init()
        self.some = some
    }
}

class D: C {
    // no need in required init(some: Int)...
}
0

A class initializer can be marked with required to indicate that every subclass of the class must implement that initializer.

As a subclass, you can use a designated initializer or a convenience initializer to satisfy this requirement.

linimin
  • 6,239
  • 2
  • 26
  • 31