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
~~~~~~~~~~~~~~~~~~~
