Object Initialization
=====================

.. warning:: This document is incomplete and not up-to-date; it currently
  describes the initialization model from Swift 1.0.

.. contents::

Introduction
------------

*Object initialization* is the process by which a new object is
allocated, its stored properties initialized, and any additional setup
tasks are performed, including allowing its superclass's to perform
their own initialization. *Object teardown* is the reverse process,
performing teardown tasks, destroying stored properties, and
eventually deallocating the object.

Initializers
------------

An initializer is responsible for the initialization of an
object. Initializers are introduced with the ``init`` keyword. For
example::

  class A {
    var i: Int
    var s: String

    init int(i: Int) string(s: String) {
      self.i = i
      self.s = s
      completeInit()
    }

    func completeInit() { /* ... */ }
  }

Here, the class ``A`` has an initializer that accepts an ``Int`` and a
``String``, and uses them to initialize its two stored properties,
then calls another method to perform other initialization tasks. The
initializer can be invoked by constructing a new ``A`` object::

  var a = A(int: 17, string: "Seventeen")

The allocation of the new ``A`` object is implicit in the
construction syntax, and cannot be separated from the call to the
initializer.

Within an initializer, all of the stored properties must be
initialized (via an assignment) before ``self`` can be used in any
way. For example, the following would produce a compiler error::

    init int(i: Int) string(s: String) {
      completeInit() // error: variable 'self.i' used before being initialized
      self.i = i
      self.s = s
    }

A stored property with an initial value declared within the class is
considered to be initialized at the beginning of the initializer. For
example, the following is a valid initializer::

  class A2 {
    var i: Int = 17
    var s: String = "Seventeen"

    init int(i: Int) string(s: String) {
      // okay: i and s are both initialized in the class
      completeInit()
    }

    func completeInit() { /* ... */ }
  }

After all stored properties have been initialized, one is free to use
``self`` in any manner.

Designated Initializers
~~~~~~~~~~~~~~~~~~~~~~~

There are two kinds of initializers in Swift: designated initializers
and convenience initializers. A *designated initializer* is
responsible for the primary initialization of an object, including the
initialization of any stored properties, *chaining* to one of its
superclass's designated initializers via a ``super.init`` call (if
there is a superclass), and performing any other initialization tasks,
in that order. For example, consider a subclass ``B`` of ``A``::

  class B : A {
    var d: Double

    init int(i: Int) string(s: String) {
      self.d = Double(i)            // initialize stored properties
      super.init(int: i, string: s) // chain to superclass
      completeInitForB()            // perform other tasks
    }

    func completeInitForB() { /* ... */ }
  }

Consider the following construction of an object of type ``B``::

  var b = B(int: 17, string: "Seventeen")

.. sidebar:: Note

  Swift differs from many other languages in that it requires one to
  initialize stored properties *before* chaining to the superclass
  initializer. This is part of Swift's memory safety guarantee, and
  is discussed further in the section on `Three-Phase
  Initialization`_.

Initialization proceeds in several steps:

1. An object of type ``B`` is allocated by the runtime.
2. ``B``'s initializer initializes the stored property ``d`` to
   ``17.0``.
3. ``B``'s initializer chains to ``A``'s initializer.
4. ``A``'s initializer initialize's the stored properties ``i`` and
   ``s``'.
5. ``A``'s initializer calls ``completeInit()``, then returns.
6. ``B``'s initializer calls ``completeInitForB()``, then returns.

A class generally has a small number of designated initializers, which
act as funnel points through which the object will be
initialized. All of the designated initializers for a class must be
written within the class definition itself, rather than in an
extension, because the complete set of designated initializers is part
of the interface contract with subclasses of a class.

The other, non-designated initializers of a class are called
convenience initializers, which tend to provide additional
initialization capabilities that are often more convenient for common
tasks.

Convenience Initializers
~~~~~~~~~~~~~~~~~~~~~~~~

A *convenience initializer* is an initializer that provides an
alternative interface to the designated initializers of a class. A
convenience initializer is denoted by the return type ``Self`` in the
definition. Unlike designated initializers, convenience initializers
can be defined either in the class definition itself or within an
extension of the class. For example::

  extension A {
    init() -> Self {
      self.init(int: 17, string: "Seventeen")
    }
  }

A convenience initializer cannot initialize the stored properties of
the class directly, nor can it invoke a superclass initializer via
``super.init``. Rather, it must *dispatch* to another initializer
using ``self.init``, which is then responsible for initializing the
object. A convenience initializer is not permitted to access ``self``
(or anything that depends on ``self``, such as one of its properties)
prior to the ``self.init`` call, although it may freely access
``self`` after ``self.init``.

Convenience initializers and designated initializers can both be used
to construct objects, using the same syntax. For example, the ``A``
initializer above can be used to build a new ``A`` object without any
arguments::

  var a2 = A() // uses convenience initializer

Initializer Inheritance
~~~~~~~~~~~~~~~~~~~~~~~

One of the primary benefits of convenience initializers is that they
can be inherited by subclasses. Initializer inheritance eliminates the
need to repeat common initialization code---such as initial values of
stored properties not easily written in the class itself, or common
registration tasks that occur during initialization---while using the
same initialization syntax. For example, this allows a ``B`` object to
be constructed with no arguments by using the inherited convenience
initializer defined in the previous section::

  var b2 = B()

Initialization proceeds as follows:

1. A ``B`` object is allocated by the runtime.
2. ``A``'s convenience initializer ``init()`` is invoked.
3. ``A``'s convenience initializer dispatches to ``init int:string:``
   via the ``self.init`` call. This call dynamically resolves to
   ``B``'s designated initializer.
4. ``B``'s designated initializer initializes the stored property
   ``d`` to ``17.0``.
5. ``B``'s designated initializer chains to ``A``'s designated
   initializer.
6. ``A``'s designated initializer initialize's the stored properties
   ``i`` and ``s``'.
7. ``A``'s designated initializer calls ``completeInit()``, then
   returns.
8. ``B``'s designated initializer calls ``completeInitForB()``, then
   returns.
9. ``A``'s convenience initializer returns.

Convenience initializers are only inherited under certain
circumstances. Specifically, for a given subclass to inherit the
convenience initializers of its superclass, the subclass must override
each of the designated initializers of its superclass. For example
``B`` provides the initializer ``init int:string:``, which overrides
``A``'s designated initializer ``init int:string:`` because the
initializer name and parameters are the same. If we had some other
subclass ``OtherB`` of ``A`` that did not provide such an override, it
would not inherit ``A``'s convenience initializers::

  class OtherB : A {
    var d: Double

    init int(i: Int) string(s: String) double(d: Double) {
      self.d = d                    // initialize stored properties
      super.init(int: i, string: s) // chain to superclass
    }
  }

  var ob = OtherB()   // error: A's convenience initializer init() not inherited

.. sidebar:: Note

  The requirement that a subclass override all of the designated
  initializers of its superclass to enable initializer inheritance is
  crucial to Swift's memory safety model. See `Initializer
  Inheritance Model`_ for more information.

Note that a subclass may have different designated initializers from
its superclass. This can occur in a number of ways. For example, the
subclass might override one of its superclass's designated
initializers with a convenience initializer::

  class YetAnotherB : A {
    var d: Double

    init int(i: Int) string(s: String) -> Self {
      self.init(int: i, string: s, double: Double(i)) // dispatch
    }

    init int(i: Int) string(s: String) double(d: Double) {
      self.d = d                    // initialize stored properties
      super.init(int: i, string: s) // chain to superclass
    }
  }

  var yab = YetAnotherB()   // okay: YetAnotherB overrides all of A's designated initializers

In other cases, it's possible that the convenience initializers of the
superclass simply can't be made to work, because the subclass
initializers require additional information provided via a
parameter that isn't present in the convenience initializers of the
superclass::

  class PickyB : A {
    var notEasy: NoEasyDefault

    init int(i: Int) string(s: String) notEasy(NoEasyDefault) {
      self.notEasy = notEasy
      super.init(int: i, string: s) // chain to superclass
    }
  }

Here, ``PickyB`` has a stored property of a type ``NoEasyDefault``
that can't easily be given a default value: it has to be provided as a
parameter to one of ``PickyB``'s initializers. Therefore, ``PickyB``
takes over responsibility for its own initialization, and
none of ``A``'s convenience initializers will be inherited into
``PickyB``.

Synthesized Initializers
~~~~~~~~~~~~~~~~~~~~~~~~

When a particular class does not specify any designated initializers,
the implementation will synthesize initializers for the class when all
of the class's stored properties have initial values in the class. The
form of the synthesized initializers depends on the superclass (if
present).

When a superclass is present, the compiler synthesizes a new
designated initializer in the subclass for each designated initializer
of the superclass. For example, consider the following class ``C``::

  class C : B {
    var title: String = "Default Title"
  }

The superclass ``B`` has a single designated initializer,::

  init int(i: Int) string(s: String)

Therefore, the compiler synthesizes the following designated
initializer in ``C``, which chains to the corresponding designated
initializer in the superclass::

  init int(i: Int) string(s: String) {
    // title is already initialized in the class C
    super.init(int: i, string: s)
  }

The result of this synthesis is that all designated initializers of
the superclass are (automatically) overridden in the subclass,
becoming designated initializers of the subclass as well. Therefore,
any convenience initializers in the superclass are also inherited,
allowing the subclass (``C``) to be constructed with the same
initializers as the superclass (``B``)::

  var c1 = C(int: 17, string: "Seventeen")
  var c2 = C()

When the class has no superclass, a default initializer (with no
parameters) is implicitly defined::

  class D {
    var title = "Default Title"

    /* implicitly defined */
    init() { }
  }

  var d = D() // uses implicitly-defined default initializer

Required Initializers
~~~~~~~~~~~~~~~~~~~~~

Objects are generally constructed with the construction syntax
``T(...)`` used in all of the examples above, where ``T`` is the name
of the type. However, it is occasionally useful to construct an object
for which the actual type is not known until runtime. For example, one
might have a ``View`` class that expects to be initialized with a
specific set of coordinates::

  struct Rect {
    var origin: (Int, Int)
    var dimensions: (Int, Int)
  }

  class View {
    init frame(Rect) { /* initialize view */ }
  }

The actual initialization of a subclass of ``View`` would then be
performed at runtime, with the actual subclass being determined via
some external file that describes the user interface. The actual
instantiation of the object would use a type value::

  func createView(_ viewClass: View.Type, frame: Rect) -> View {
    return viewClass(frame: frame) // error: 'init frame:' is not 'required'
  }

The code above is invalid because there is no guarantee that a given
subclass of ``View`` will have an initializer ``init frame:``, because
the subclass might have taken over its own initialization (as with
``PickyB``, above). To require that all subclasses provide a
particular initializer, use the ``required`` attribute as follows::

  class View {
    @required init frame(Rect) {
      /* initialize view */
    }
  }

  func createView(_ viewClass: View.Type, frame: Rect) -> View {
    return viewClass(frame: frame) // okay
  }

The ``required`` attribute allows the initializer to be used to
construct an object of a dynamically-determined subclass, as in the
``createView`` method. It places the (transitive) requirement on all
subclasses of ``View`` to provide an initializer ``init frame:``. For
example, the following ``Button`` subclass would produce an error::

  class Button : View {
    // error: 'Button' does not provide required initializer 'init frame:'.
  }

The fix is to implement the required initializer in ``Button``::

  class Button : View {
    @required init frame(Rect) { // okay: satisfies requirement
      super.init(frame: frame)
    }
  }

Initializers in Protocols
~~~~~~~~~~~~~~~~~~~~~~~~~

Initializers may be declared within a protocol. For example::

  protocol DefaultInitializable {
    init()
  }

.. sidebar:: Note

  Initializers in protocols have not yet been implemented. Stay tuned.

A class can satisfy this requirement by providing a required
initializer. For example, only the first of the two following classes
conforms to its protocol::

  class DefInit : DefaultInitializable {
    @required init() { }
  }

  class AlmostDefInit : DefaultInitializable {
    init() { } // error: initializer used for protocol conformance must be 'required'
  }

The ``required`` requirement ensures that all subclasses of the class
declaring conformance to the protocol will also have the initializer,
so they too will conform to the protocol. This allows one to construct
objects given type values of protocol type::

  func createAnyDefInit(_ typeVal: DefaultInitializable.Type) -> DefaultInitializable {
    return typeVal()
  }

De-initializers
~~~~~~~~~~~~~~~

While initializers are responsible for setting up an object's state,
*de-initializers* are responsible for tearing down that state. Most
classes don't require a de-initializer, because Swift automatically
releases all stored properties and calls to the superclass's
de-initializer. However, if your class has allocated a resource that
is not an object (say, a Unix file descriptor) or has registered
itself during initialization, one can write a de-initializer using
``deinit``::

  class FileHandle {
    var fd: Int32

    init withFileDescriptor(fd: Int32) {
      self.fd = fd
    }

    deinit {
      close(fd)
    }
  }

The statements within a de-initializer (here, the call to ``close``)
execute first, then the superclass's de-initializer is
called. Finally, stored properties are released and the object is
deallocated.

Methods Returning ``Self``
~~~~~~~~~~~~~~~~~~~~~~~~~~


A class method can have the special return type ``Self``, which refers
to the dynamic type of ``self``. Such a method guarantees that it will
return an object with the same dynamic type as ``self``. One of the
primary uses of the ``Self`` return type is for factory methods::

  extension View {
    class func createView(_ frame: Rect) -> Self {
      return self(frame: frame)
    }
  }

.. sidebar:: Note

  The return type ``Self`` fulfills the same role as Objective-C's
  ``instancetype``, although Swift provides stronger type checking for
  these methods.

Within the body of this class method, the implicit parameter ``self``
is a value with type ``View.Type``, i.e., it's a type value for the
class ``View`` or one of its subclasses. Therefore, the restrictions
are the same as for any value of type ``View.Type``: one can call
other class methods and construct new objects using required
initializers of the class, among other things. The result returned
from such a method must be derived from the type of ``Self``. For
example, it cannot return a value of type ``View``, because ``self``
might refer to some subclass of ``View``.

Instance methods can also return ``Self``. This is typically used to
allow chaining of method calls by returning ``Self`` from each method,
as in the builder pattern::

  class DialogBuilder {
    func setTitle(_ title: String) -> Self {
      // set the title
      return self;
    }

    func setBounds(_ frame: Rect) -> Self {
      // set the bounds
      return self;
    }
  }

  var builder = DialogBuilder()
                  .setTitle("Hello, World!")
                  .setBounds(Rect(0, 0, 640, 480))


Memory Safety
-------------

Swift aims to provide memory safety by default, and much of the design
of Swift's object initialization scheme is in service of that
goal. This section describes the rationale for the design based on the
memory-safety goals of the language.

Three-Phase Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~

The three-phase initialization model used by Swift's initializers
ensures that all stored properties get initialized before any code can
make use of ``self``. This is important uses of ``self``---say,
calling a method on ``self``---could end up referring to stored
properties before they are initialized. Consider the following
Objective-C code, where instance variables are initialized *after* the
call to the superclass initializer::

  @interface A : NSObject
  - (instancetype)init;
  - (void)finishInit;
  @end

  @implementation A
  - (instancetype)init {
    self = [super init];
    if (self) {
      [self finishInit];
    }
    return self;
  }
  @end

  @interface B : A
  @end

  @implementation B {
    NSString *ivar;
  }

  - (instancetype)init {
    self = [super init];
    if (self) {
      self->ivar = @"Default name";
    }
    return self;
  }

  - (void) finishInit {
    NSLog(@"ivar has the value %@\n", self->ivar);
  }
  @end

.. sidebar:: Notes

  In Objective-C, ``+alloc`` zero-initializes all of the instance
  variables, which gives them predictable behavior before the init
  method gets to initialize them. Given that Objective-C is fairly
  resilient to ``nil`` objects, this default behavior eliminates (or
  hides) many such initialization bugs. In Swift, however, the
  zero-initialized state is less likely to be valid, and the memory
  safety goals are stronger, so zero-initialization does not suffice.

When initializing a ``B`` object, the ``NSLog`` statement will print::

  ivar has the value (null)

because ``-[B finishInit]`` executes before ``B`` has had a chance to
initialize its instance variables. Swift initializers avoid this issue
by splitting each initializer into three phases:

1. Initialize stored properties. In this phase, the compiler verifies
that ``self`` is not used except when writing to the stored properties
of the current class (not its superclasses!). Additionally, this
initialization directly writes to the storage of the stored
properties, and does not call any setter or ``willSet``/``didSet``
method. In this phase, it is not possible to read any of the stored
properties.

2. Call to superclass initializer, if any. As with the first step,
``self`` cannot be accessed at all.

3. Perform any additional initialization tasks, which may call methods
on ``self``, access properties, and so on.

Note that, with this scheme, ``self`` cannot be used until the
original class and all of its superclasses have initialized their
stored properties, closing the memory safety hole.


Initializer Inheritance Model
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FIXME: To be written

Objective-C Interoperability
----------------------------

Initializers and Init Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Designated and Convenience Initializers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Allocation and Deallocation
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Dynamic Subclassing
~~~~~~~~~~~~~~~~~~~
