# Setting Initial Values for Stored Properties

> Set the initial values for a type's stored properties and perform one-time setup.

- Skill: `tools-only/setting-initial-values-for-stored-properties` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/setting-initial-values-for-stored-properties`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/setting-initial-values-for-stored-properties/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/setting-initial-values-for-stored-properties

---

# Initialization

Set the initial values for a type's stored properties and perform one-time setup.

*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's required
before the new instance is ready for use.

You implement this initialization process by defining *initializers*,
which are like special methods that can be called
to create a new instance of a particular type.
Unlike Objective-C initializers, Swift initializers don't return a value.
Their primary role is to ensure that new instances of a type
are correctly initialized before they're used for the first time.

Instances of class types can also implement a *deinitializer*,
which performs any custom cleanup just before an instance of that class is deallocated.
For more information about deinitializers, see <doc:Deinitialization>.

## Setting Initial Values for Stored Properties

Classes and structures *must* set all of their stored properties
to an appropriate initial value by the time
an instance of that class or structure is created.
Stored properties can't be left in an indeterminate state.

You can set an initial value for a stored property within an initializer,
or by assigning a default property value as part of the property's definition.
These actions are described in the following sections.

> Note: When you assign a default value to a stored property,
> or set its value within an initializer,
> the value of that property is set directly,
> without calling any property observers.

### Initializers

*Initializers* are called to create a new instance of a particular type.
In its simplest form, an initializer is like an instance method with no parameters,
written using the `init` keyword:

```swift
init() {
    // perform some initialization here
}
```

<!--
  - test: `initializerSyntax`

  ```swifttest
  >> class Test {
  -> init() {
        // perform some initialization here
     }
  >> }
  ```
-->

The example below defines a new structure called `Fahrenheit`
to store temperatures expressed in the Fahrenheit scale.
The `Fahrenheit` structure has one stored property,
`temperature`, which is of type `Double`:

```swift
struct Fahrenheit {
    var temperature: Double
    init() {
        temperature = 32.0
    }
}
var f = Fahrenheit()
print("The default temperature is \(f.temperature)° Fahrenheit")
// Prints "The default temperature is 32.0° Fahrenheit".
```

<!--
  - test: `fahrenheitInit`

  ```swifttest
  -> struct Fahrenheit {
        var temperature: Double
        init() {
           temperature = 32.0
        }
     }
  -> var f = Fahrenheit()
  -> print("The default temperature is \(f.temperature)° Fahrenheit")
  <- The default temperature is 32.0° Fahrenheit
  ```
-->

The structure defines a single initializer, `init`, with no parameters,
which initializes the stored temperature with a value of `32.0`
(the freezing point of water in degrees Fahrenheit).

### Default Property Values

You can set the initial value of a stored property from within an initializer,
as shown above.
Alternatively, specify a *default property value*
as part of the property's declaration.
You specify a default property value by assigning an initial value to the property
when it's defined.

> Note: If a property always takes the same initial value,
> provide a default value rather than setting a value within an initializer.
> The end result is the same,
> but the default value ties the property's initialization more closely to its declaration.
> It makes for shorter, clearer initializers
> and enables you to infer the type of the property from its default value.
> The default value also makes it easier for you to take advantage of
> default initializers and initializer inheritance,
> as described later in this chapter.

You can write the `Fahrenheit` structure from above in a simpler form
by providing a default value for its `temperature` property
at the point that the property is declared:

```swift
struct Fahrenheit {
    var temperature = 32.0
}
```

<!--
  - test: `fahrenheitDefault`

  ```swifttest
  -> struct Fahrenheit {
        var temperature = 32.0
     }
  ```
-->

## Customizing Initialization

You can customize the initialization process
with input parameters and optional property types,
or by assigning constant properties during initialization,
as described in the following sections.

### Initialization Parameters

You can provide *initialization parameters* as part of an initializer's definition,
to define the types and names of values that customize the initialization process.
Initialization parameters have the same capabilities and syntax
as function and method parameters.

The following example defines a structure called `Celsius`,
which stores temperatures expressed in degrees Celsius.
The `Celsius` structure implements two custom initializers called
`init(fromFahrenheit:)` and `init(fromKelvin:)`,
which initialize a new instance of the structure
with a value from a different temperature scale:

```swift
struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0
```

<!--
  - test: `initialization`

  ```swifttest
  -> struct Celsius {
        var temperatureInCelsius: Double
        init(fromFahrenheit fahrenheit: Double) {
           temperatureInCelsius = (fahrenheit - 32.0) / 1.8
        }
        init(fromKelvin kelvin: Double) {
           temperatureInCelsius = kelvin - 273.15
        }
     }
  -> let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
  /> boilingPointOfWater.temperatureInCelsius is \(boilingPointOfWater.temperatureInCelsius)
  </ boilingPointOfWater.temperatureInCelsius is 100.0
  -> let freezingPointOfWater = Celsius(fromKelvin: 273.15)
  /> freezingPointOfWater.temperatureInCelsius is \(freezingPointOfWater.temperatureInCelsius)
  </ freezingPointOfWater.temperatureInCelsius is 0.0
  ```
-->

The first initializer has a single initialization parameter
with an argument label of `fromFahrenheit` and a parameter name of `fahrenheit`.
The second initializer has a single initialization parameter
with an argument label of `fromKelvin` and a parameter name of `kelvin`.
Both initializers convert their single argument into
the corresponding Celsius value
and store this value in a property called `temperatureInCelsius`.

<!--
  TODO: I need to provide an example of default values for initializer parameters,
  to show they can help you to get multiple initializers "for free" (after a fashion).
-->

### Parameter Names and Argument Labels

As with function and method parameters,
initialization parameters can have both a parameter name
for use within the initializer's body
and an argument label for use when calling the initializer.

However, initializers don't have an identifying function name before their parentheses
in the way that functions and methods do.
Therefore, the names and types of an initializer's parameters
play a particularly important role in identifying which initializer should be called.
Because of this, Swift provides an automatic argument label
for *every* parameter in an initializer if you don't provide one.

The following example defines a structure called `Color`,
with three constant properties called `red`, `green`, and `blue`.
These properties store a value between `0.0` and `1.0`
to indicate the amount of red, green, and blue in the color.

`Color` provides an initializer with
three appropriately named parameters of type `Double`
for its red, green, and blue components.
`Color` also provides a second initializer with a single `white` parameter,
which is used to provide the same value for all three color components.

```swift
struct Color {
    let red, green, blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red   = red
        self.green = green
        self.blue  = blue
    }
    init(white: Double) {
        red   = white
        green = white
        blue  = white
    }
}
```

<!--
  - test: `externalParameterNames, externalParameterNames-err`

  ```swifttest
  -> struct Color {
        let red, green, blue: Double
        init(red: Double, green: Double, blue: Double) {
           self.red   = red
           self.green = green
           self.blue  = blue
        }
        init(white: Double) {
           red   = white
           green = white
           blue  = white
        }
     }
  ```
-->

Both initializers can be used to create a new `Color` instance,
by providing named values for each initializer parameter:

```swift
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
let halfGray = Color(white: 0.5)
```

<!--
  - test: `externalParameterNames`

  ```swifttest
  -> let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
  -> let halfGray = Color(white: 0.5)
  >> assert(halfGray.red == 0.5)
  >> assert(halfGray.green == 0.5)
  >> assert(halfGray.blue == 0.5)
  ```
-->

Note that it isn't possible to call these initializers
without using argument labels.
Argument labels must always be used in an initializer if they're defined,
and omitting them is a compile-time error:

```swift
let veryGreen = Color(0.0, 1.0, 0.0)
// this reports a compile-time error - argument labels are required
```

<!--
  - test: `externalParameterNames-err`

  ```swifttest
  -> let veryGreen = Color(0.0, 1.0, 0.0)
  // this reports a compile-time error - argument labels are required
  !$ error: missing argument labels 'red:green:blue:' in call
  !! let veryGreen = Color(0.0, 1.0, 0.0)
  !! ^
  !! red: green:  blue:
  ```
-->

### Initializer Parameters Without Argument Labels

If you don't want to use an argument label for an initializer parameter,
write an underscore (`_`) instead of an explicit argument label for that parameter
to override the default behavior.

Here's an expanded version of the `Celsius` example
from <doc:Initialization#Initialization-Parameters> above,
with an additional initializer to create a new `Celsius` instance
from a `Double` value that's already in the Celsius scale:

```swift
struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
    init(_ celsius: Double) {
        temperatureInCelsius = celsius
    }
}
let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius is 37.0
```

<!--
  - test: `initializersWithoutExternalParameterNames`

  ```swifttest
  -> struct Celsius {
        var temperatureInCelsius: Double
        init(fromFahrenheit fahrenheit: Double) {
           temperatureInCelsius = (fahrenheit - 32.0) / 1.8
        }
        init(fromKelvin kelvin: Double) {
           temperatureInCelsius = kelvin - 273.15
        }
        init(_ celsius: Double) {
           temperatureInCelsius = celsius
        }
     }
  -> let bodyTemperature = Celsius(37.0)
  /> bodyTemperature.temperatureInCelsius is \(bodyTemperature.temperatureInCelsius)
  </ bodyTemperature.temperatureInCelsius is 37.0
  ```
-->

The initializer call `Celsius(37.0)` is clear in its intent
without the need for an argument label.
It's therefore appropriate to write this initializer as `init(_ celsius: Double)`
so that it can be called by providing an unnamed `Double` value.

### Optional Property Types

If your custom type has a stored property that's logically allowed to have “no value” ---
perhaps because its value can't be set during initialization,
or because it's allowed to have “no value” at some later point ---
declare the property with an *optional* type.
Properties of optional type are automatically initialized with a value of `nil`,
indicating that the property is deliberately intended to have “no value yet”
during initialization.

The following example defines a class called `SurveyQuestion`,
with an optional `String` property called `response`:

```swift
class SurveyQuestion {
    var text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
cheeseQuestion.ask()
// Prints "Do you like cheese?"
cheeseQuestion.response = "Yes, I do like cheese."
```

<!--
  - test: `surveyQuestionVariable`

  ```swifttest
  -> class SurveyQuestion {
        var text: String
        var response: String?
        init(text: String) {
           self.text = text
        }
        func ask() {
           print(text)
        }
     }
  -> let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
  -> cheeseQuestion.ask()
  <- Do you like cheese?
  -> cheeseQuestion.response = "Yes, I do like cheese."
  ```
-->

The response to a survey question can't be known until it's asked,
and so the `response` property is declared with a type of `String?`,
or “optional `String`”.
It's automatically assigned a default value of `nil`, meaning “no string yet”,
when a new instance of `SurveyQuestion` is initialized.

### Assigning Constant Properties During Initialization

You can assign a value to a constant property
at any point during initialization,
as long as it's set to a definite value by the time initialization finishes.
Once a constant property is assigned a value,
it can't be further modified.

<!--
  - test: `constantPropertyAssignment`

  ```swifttest
  >> struct S {
        let c: Int
        init() {
           self.c = 1
           self.c = 2
        }
     }
  !$ error: immutable value 'self.c' may only be initialized once
  !! self.c = 2
  !! ^
  !$ note: change 'let' to 'var' to make it mutable
  !! let c: Int
  !! ^~~
  !! var
  ```
-->

<!--
  - test: `constantPropertyAssignmentWithInitialValue`

  ```swifttest
  >> struct S {
        let c: Int = 0
        init() {
           self.c = 1
        }
     }
  !$ error: immutable value 'self.c' may only be initialized once
  !! self.c = 1
  !! ^
  !$ note: initial value already provided in 'let' declaration
  !! let c: Int = 0
  !! ^
  !$ note: change 'let' to 'var' to make it mutable
  !! let c: Int = 0
  !! ^~~
  !! var
  ```
-->

> Note: For class instances,
> a constant property can be modified during initialization
> only by the class that introduces it.
> It can't be modified by a subclass.

You can revise the `SurveyQuestion` example from above to use
a constant property rather than a variable property for the `text` property of the question,
to indicate that the question doesn't change once an instance of `SurveyQuestion` is created.
Even though the `text` property is now a constant,
it can still be set within the class's initializer:

```swift
class SurveyQuestion {
    let text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
let beetsQuestion = SurveyQuestion(text: "How about beets?")
beetsQuestion.ask()
// Prints "How about beets?"
beetsQuestion.response = "I also like beets. (But not with cheese.)"
```

<!--
  - test: `surveyQuestionConstant`

  ```swifttest
  -> class SurveyQuestion {
        let text: String
        var response: String?
        init(text: String) {
           self.text = text
        }
        func ask() {
           print(text)
        }
     }
  -> let beetsQuestion = SurveyQuestion(text: "How about beets?")
  -> beetsQuestion.ask()
  <- How about beets?
  -> beetsQuestion.response = "I also like beets. (But not with cheese.)"
  ```
-->

## Default Initializers

Swift provides a *default initializer*
for any structure or class
that provides default values for all of its properties
and doesn't provide at least one initializer itself.
The default initializer simply creates a new instance
with all of its properties set to their default values.

<!--
  - test: `defaultInitializersForStructAndClass`

  ```swifttest
  -> struct S { var s: String = "s" }
  -> assert(S().s == "s")
  -> class A { var a: String = "a" }
  -> assert(A().a == "a")
  -> class B: A { var b: String = "b" }
  -> assert(B().a == "a")
  -> assert(B().b ==  "b")
  ```
-->

This example defines a class called `ShoppingListItem`,
which encapsulates the name, quantity, and purchase state
of an item in a shopping list:

```swift
class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()
```

<!--
  - test: `initialization`

  ```swifttest
  -> class ShoppingListItem {
        var name: String?
        var quantity = 1
        var purchased = false
     }
  -> var item = ShoppingListItem()
  ```
-->

Because all properties of the `ShoppingListItem` class have default values,
and because it's a base class with no superclass,
`ShoppingListItem` automatically gains a default initializer implementation
that creates a new instance with all of its properties set to their default values.
(The `name` property is an optional `String` property,
and so it automatically receives a default value of `nil`,
even though this value isn't written in the code.)
The example above uses the default initializer for the `ShoppingListItem` class
to create a new instance of the class with initializer syntax,
written as `ShoppingListItem()`,
and assigns this new instance to a variable called `item`.

### Memberwise Initializers for Structure Types

Structure types automatically receive a *memberwise initializer*
if they don't define any of their own custom initializers.
Unlike a default initializer,
the structure receives a memberwise initializer
even if it has stored properties that don't have default values.

<!--
  - test: `memberwiseInitializersDontRequireDefaultStoredPropertyValues`

  ```swifttest
  -> struct S { var int: Int; var string: String }
  -> let s = S(int: 42, string: "hello")

  -> struct SS { var int = 10; var string: String }
  -> let ss = SS(int: 42, string: "hello")
  ```
-->

The memberwise initializer is a shorthand way
to initialize the member properties of new structure instances.
Initial values for the properties of the new instance
can be passed to the memberwise initializer by name.

The example below defines a structure called `Size`
with two properties called `width` and `height`.
Both properties are inferred to be of type `Double`
by assigning a default value of `0.0`.

The `Size` structure automatically receives an `init(width:height:)`
memberwise initializer,
which you can use to initialize a new `Size` instance:

```swift
struct Size {
    var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)
```

<!--
  - test: `initialization`

  ```swifttest
  -> struct Size {
        var width = 0.0, height = 0.0
     }
  -> let twoByTwo = Size(width: 2.0, height: 2.0)
  ```
-->

When you call a memberwise initializer,
you can omit values for any properties
that have default values.
In the example above,
the `Size` structure has a default value
for both its `height` and `width` properties.
You can omit either property or both properties,
and the initializer uses the default value for anything you omit.
For example:

```swift
let zeroByTwo = Size(height: 2.0)
print(zeroByTwo.width, zeroByTwo.height)
// Prints "0.0 2.0".

let zeroByZero = Size()
print(zeroByZero.width, zeroByZero.height)
// Prints "0.0 0.0".
```

<!--
  - test: `initialization`

  ```swifttest
  -> let zeroByTwo = Size(height: 2.0)
  -> print(zeroByTwo.width, zeroByTwo.height)
  <- 0.0 2.0

  -> let zeroByZero = Size()
  -> print(zeroByZero.width, zeroByZero.height)
  <- 0.0 0.0
  ```
-->

## Initializer Delegation for Value Types

Initializers can call other initializers to perform part of an instance's initialization.
This process, known as *initializer delegation*,
avoids duplicating code across multiple initializers.

The rules for how initializer delegation works,
and for what forms of delegation are allowed,
are different for value types and class types.
Value types (structures and enumerations) don't support inheritance,
and so their initializer delegation process is relatively simple,
because they can only delegate to another initializer that they provide themselves.
Classes, however, can inherit from other classes,
as described in <doc:Inheritance>.
This means that classes have additional responsibilities for ensuring that
all stored properties they inherit are assigned a suitable value during initialization.
These responsibilities are described in
<doc:Initialization#Class-Inheritance-and-Initialization> below.

For value types, you use `self.init` to refer to other initializers
from the same value type when writing your own custom initializers.
You can call `self.init` only from within an initializer.

Note that if you define a custom initializer for a value type,
you will no longer have access to the default initializer
(or the memberwise initializer, if it's a structure) for that type.
This constraint prevents a situation in which additional essential setup
provided in a more complex initializer
is accidentally circumvented by someone using one of the automatic initializers.

> Note: If you want your custom value type to be initializable with
> the default initializer and memberwise initializer,
> and also with your own custom initializers,
> write your custom initializers in an extension
> rather than as part of the value type's original implementation.
> For more information, see <doc:Extensions>.

The following example defines a custom `Rect` structure to represent a geometric rectangle.
The example requires two supporting structures called `Size` and `Point`,
both of which provide default values of `0.0` for all of their properties:

```swift
struct Size {
    var width = 0.0, height = 0.0
}
struct Point {
    var x = 0.0, y = 0.0
}
```

<!--
  - test: `valueDelegation`

  ```swifttest
  -> struct Size {
        var width = 0.0, height = 0.0
     }
  -> struct Point {
        var x = 0.0, y = 0.0
     }
  ```
-->

You can initialize the `Rect` structure below in one of three ways ---
by using its default zero-initialized `origin` and `size` property values,
by providing a specific origin point and size,
or by providing a specific center point and size.
These initialization options are represented by
three custom initializers that are part of the `Rect` structure's definition:

```swift
struct Rect {
    var origin = Point()
    var size = Size()
    init() {}
    init(origin: Point, size: Size) {
        self.origin = origin
        self.size = size
    }
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}
```

<!--
  - test: `valueDelegation`

  ```swifttest
  -> struct Rect {
        var origin = Point()
        var size = Size()
        init() {}
        init(origin: Point, size: Size) {
           self.origin = origin
           self.size = size
        }
        init(center: Point, size: Size) {
           let originX = center.x - (size.width / 2)
           let originY = center.y - (size.height / 2)
           self.init(origin: Point(x: originX, y: originY), size: size)
        }
     }
  ```
-->

The first `Rect` initializer, `init()`,
is functionally the same as the default initializer that the structure would have received
if it didn't have its own custom initializers.
This initializer has an empty body,
represented by an empty pair of curly braces `{}`.
Calling this initializer returns a `Rect` instance whose
`origin` and `size` properties are both initialized with
the default values of `Point(x: 0.0, y: 0.0)`
and `Size(width: 0.0, height: 0.0)`
from their property definitions:

```swift
let basicRect = Rect()
// basicRect's origin is (0.0, 0.0) and its size is (0.0, 0.0)
```

<!--
  - test: `valueDelegation`

  ```swifttest
  -> let basicRect = Rect()
  /> basicRect's origin is (\(basicRect.origin.x), \(basicRect.origin.y)) and its size is (\(basicRect.size.width), \(basicRect.size.height))
  </ basicRect's origin is (0.0, 0.0) and its size is (0.0, 0.0)
  ```
-->

The second `Rect` initializer, `init(origin:size:)`,
is functionally the same as the memberwise initializer that the structure would have received
if it didn't have its own custom initializers.
This initializer simply assigns the `origin` and `size` argument values to
the appropriate stored properties:

```swift
let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
    size: Size(width: 5.0, height: 5.0))
// originRect's origin is (2.0, 2.0) and its size is (5.0, 5.0)
```

<!--
  - test: `valueDelegation`

  ```swifttest
  -> let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
        size: Size(width: 5.0, height: 5.0))
  /> originRect's origin is (\(originRect.origin.x), \(originRect.origin.y)) and its size is (\(originRect.size.width), \(originRect.size.height))
  </ originRect's origin is (2.0, 2.0) and its size is (5.0, 5.0)
  ```
-->

The third `Rect` initializer, `init(center:size:)`, is slightly more complex.
It starts by calculating an appropriate origin point based on
a `center` point and a `size` value.
It then calls (or *delegates*) to the `init(origin:size:)` initializer,
which stores the new origin and size values in the appropriate properties:

```swift
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
    size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)
```

<!--
  - test: `valueDelegation`

  ```swifttest
  -> let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
        size: Size(width: 3.0, height: 3.0))
  /> centerRect's origin is (\(centerRect.origin.x), \(centerRect.origin.y)) and its size is (\(centerRect.size.width), \(centerRect.size.height))
  </ centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)
  ```
-->

The `init(center:size:)` initializer could have assigned
the new values of `origin` and `size` to the appropriate properties itself.
However, it's more convenient (and clearer in intent)
for the `init(center:size:)` initializer to take advantage of an existing initializer
that already provides exactly that functionality.

> Note: For an alternative way to write this example without defining
> the `init()` and `init(origin:size:)` initializers yourself,
> see <doc:Extensions>.

## Class Inheritance and Initialization

All of a class's stored properties ---
including any properties the class inherits from its superclass ---
*must* be assigned an initial value during initialization.

Swift defines two kinds of initializers for class types
to help ensure all stored properties receive an initial value.
These are known as designated initializers and convenience initializers.

### Designated Initializers and Convenience Initializers

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

Classes tend to have very few designated initializers,
and it's quite common for a class to have only one.
Designated initializers are “funnel” points through which initialization takes place,
and through which the initialization process continues up the superclass chain.

Every class must have at least one designated initializer.
In some cases, this requirement is satisfied
by inheriting one or more designated initializers from a superclass,
as described in <doc:Initialization#Automatic-Initializer-Inheritance> below.

*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 don't have to provide convenience initializers if your class doesn't 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.

### Syntax for Designated and Convenience Initializers

Designated initializers for classes are written in the same way as
simple initializers for value types:

```swift
init(<#parameters#>) {
   <#statements#>
}
```

Convenience initializers are written in the same style,
but with the `convenience` modifier placed before the `init` keyword,
separated by a space:

```swift
convenience init(<#parameters#>) {
   <#statements#>
}
```

### Initializer Delegation for Class Types

To simplify the relationships between designated and convenience initializers,
Swift applies the following three rules for delegation calls between initializers:

- term **Rule 1**:
  A designated initializer must call a designated initializer from its immediate superclass.

- term **Rule 2**:
  A convenience initializer must call another initializer from the *same* class.

- term **Rule 3**:
  A convenience initializer must ultimately call a designated initializer.

A simple way to remember this is:

- Designated initializers must always delegate *up*.
- Convenience initializers must always delegate *across*.

These rules are illustrated in the figure below:

![](initializerDelegation01)

Here, the superclass has a single designated initializer and two convenience initializers.
One convenience initializer calls another convenience initializer,
which in turn calls the single designated initializer.
This satisfies rules 2 and 3 from above.
The superclass doesn't itself have a further superclass, and so rule 1 doesn't apply.

The subclass in this figure has two designated initializers and one convenience initializer.
The convenience initializer must call one of the two designated initializers,
because it can only call another initializer from the same class.
This satisfies rules 2 and 3 from above.
Both designated initializers must call the single designated initializer
from the superclass, to satisfy rule 1 from above.

> Note: These rules don't affect how users of your classes *create* instances of each class.
> Any initializer in the diagram above can be used to create
> a fully initialized instance of the class they belong to.
> The rules only affect how you write the implementation of the class's initializers.

The figure below shows a more complex class hierarchy for four classes.
It illustrates how the designated initializers in this hierarchy
act as “funnel” points for class initialization,
simplifying the interrelationships among classes in the chain:

![](initializerDelegation02)

### Two-Phase Initialization

Class initialization in Swift is a two-phase process.
In the first phase, each stored property is assigned an initial value
by the class that introduced it.
Once the initial state for every stored property has been determined,
the second phase begins,
and each class is given the opportunity to customize its stored properties further
before the new instance is considered ready for use.

The use of a two-phase initialization process makes initialization safe,
while still giving complete flexibility to each class in a class hierarchy.
Two-phase initialization prevents property values
from being accessed before they're initialized,
and prevents property values from being set to a different value
by another initializer unexpectedly.

> Note: Swift's two-phase initialization process is similar to initialization in Objective-C.
> The main difference is that during phase 1,
> Objective-C assigns zero or null values (such as `0` or `nil`) to every property.
> Swift's initialization flow is more flexible
> in that it lets you set custom initial values,
> and can cope with types for which `0` or `nil` isn't a valid default value.

Swift's compiler performs four helpful safety-checks to make sure that
two-phase initialization is completed without error:

- term **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.

As mentioned above,
the memory for an object is only considered fully initialized
once the initial state of all of its stored properties is known.
In order for this rule to be satisfied, a designated initializer must make sure that
all of its own properties are initialized before it hands off up the chain.

- term **Safety check 2**:
  A designated initializer must delegate up to a superclass initializer
  before assigning a value to an inherited property.
  If it doesn't, the new value the designated initializer assigns
  will be overwritten by the superclass as part of its own initialization.

- term **Safety check 3**:
  A convenience initializer must delegate to another initializer
  before assigning a value to *any* property
  (including properties defined by the same class).
  If it doesn't, the new value the convenience initializer assigns
  will be overwritten by its own class's designated initializer.

- term **Safety check 4**:
  An initializer can't call any instance methods,
  read the values of any instance properties,
  or refer to `self` as a value
  until after the first phase of initialization is complete.

The class instance isn't fully valid until the first phase ends.
Properties can only be accessed, and methods can only be called,
once the class instance is known to be valid at the end of the first phase.

Here's how two-phase initialization plays out, based on the four safety checks above:

**Phase 1**

- A designated or convenience initializer is called on a class.
- Memory for a new instance of that class is allocated.
  The memory isn't yet initialized.
- A designated initializer for that class confirms that
  all stored properties introduced by that class have a value.
  The memory for these stored properties is now initialized.
- The designated initializer hands off to a superclass initializer to perform the same task
  for its own stored properties.
- This continues up the class inheritance chain until the top of the chain is reached.
- Once the top of the chain is reached,
  and the final class in the chain has ensured that all of its stored properties have a value,
  the instance's memory is considered to be fully initialized, and phase 1 is complete.

**Phase 2**

- Working back down from the top of the chain,
  each designated initializer in the chain has the option to customize the instance further.
  Initializers are now able to access `self`
  and can modify its properties, call its instance methods, and so on.
- Finally, any convenience initializers in the chain have the option
  to customize the instance and to work with `self`.

Here's how phase 1 looks for an initialization call for a hypothetical subclass and superclass:

![](twoPhaseInitialization01)

In this example, initialization begins with a call to
a convenience initializer on the subclass.
This convenience initializer can't yet modify any properties.
It delegates across to a designated initializer from the same class.

The designated initializer makes sure that all of the subclass's properties have a value,
as per safety check 1. It then calls a designated initializer on its superclass
to continue the initialization up the chain.

The superclass's designated initializer makes sure that
all of the superclass properties have a value.
There are no further superclasses to initialize,
and so no further delegation is needed.

As soon as all properties of the superclass have an initial value,
its memory is considered fully initialized, and phase 1 is complete.

Here's how phase 2 looks for the same initialization call:

![](twoPhaseInitialization02)

The superclass's designated initializer now has an opportunity
to customize the instance further
(although it doesn't have to).

Once the superclass's designated initializer is finished,
the subclass's designated initializer can perform additional customization
(although again, it doesn't have to).

Finally, once the subclass's designated initializer is finished,
the convenience initializer that was originally called
can perform additional customization.

### Initializer Inheritance and Overriding

Unlike subclasses in Objective-C,
Swift subclasses don't inherit their superclass initializers by default.
Swift's approach prevents a situation in which a simple initializer from a superclass
is inherited by a more specialized subclass
and is used to create a new instance of the subclass
that isn't fully or correctly initialized.

> Note: Superclass initializers *are* inherited in certain circumstances,
> but only when it's safe and appropriate to do so.
> For more information, see <doc:Initialization#Automatic-Initializer-Inheritance> below.

If you want a custom subclass to present
one or more of the same initializers as its superclass,
you can provide a custom implementation of those initializers within the subclass.

When you write a subclass initializer that matches a superclass *designated* initializer,
you are effectively providing an override of that designated initializer.
Therefore, you must write the `override` modifier before the subclass's initializer definition.
This is true even if you are overriding an automatically provided default initializer,
as described in <doc:Initialization#Default-Initializers>.

As with an overridden property, method or subscript,
the presence of the `override` modifier prompts Swift to check that
the superclass has a matching designated initializer to be overridden,
and validates that the parameters for your overriding initializer have been specified as intended.

> Note: You always write the `override` modifier when overriding a superclass designated initializer,
> even if your subclass's implementation of the initializer is a convenience initializer.

<!--
  - test: `youHaveToWriteOverrideWhenOverridingADesignatedInitializer`

  ```swifttest
  -> class C {
        init() {}
     }
  -> class D1: C {
        // this is correct
        override init() {}
     }
  -> class D2: C {
        // this isn't correct
        init() {}
     }
  !$ error: overriding declaration requires an 'override' keyword
  !! init() {}
  !! ^
  !! override
  !$ note: overridden declaration is here
  !! init() {}
  !! ^
  ```
-->

<!--
  - test: `youHaveToWriteOverrideEvenWhenOverridingADefaultInitializer`

  ```swifttest
  -> class C {
        var i = 0
     }
  -> class D1: C {
        // this is correct
        override init() {}
     }
  -> class D2: C {
        // this isn't correct
        init() {}
     }
  !$ error: overriding declaration requires an 'override' keyword
  !! init() {}
  !! ^
  !! override
  !$ note: overridden declaration is here
  !! class C {
  !! ^
  ```
-->

Conversely, if you write a subclass initializer that matches a superclass *convenience* initializer,
that superclass convenience initializer can never be called directly by your subclass,
as per the rules described above in <doc:Initialization#Initializer-Delegation-for-Class-Types>.
Therefore, your subclass is not (strictly speaking) providing an override of the superclass initializer.
As a result, you don't write the `override` modifier when providing
a matching implementation of a superclass convenience initializer.

<!--
  - test: `youDoNotAndCannotWriteOverrideWhenOverridingAConvenienceInitializer`

  ```swifttest
  -> class C {
        var i: Int
        ini

…(truncated)
