:orphan:

Initialization
==============

.. contents::

Superclass Delegation
---------------------
The initializer for a class that has a superclass must ensure that its
superclass subobject gets initialized. The typical way to do so is
through the use of superclass delegation::

  class A {
    var x: Int

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

  class B : A {
    var value: String

    init() {
      value = "Hello"
      super.init(5) // superclass delegation
    }
  }

Swift implements two-phase initialization, which requires that all of
the instance variables of the subclass be initialized (either within
the class or within the initializer) before delegating to the
superclass initializer with ``super.init``.

If the superclass is a Swift class, superclass delegation is a direct
call to the named initializer in the superclass. If the superclass is
an Objective-C class, superclass delegation uses dynamic dispatch via
``objc_msgSendSuper`` (and its variants).

Peer Delegation
---------------
An initializer can delegate to one of its peer initializers, which
then takes responsibility for initializing this subobject and any
superclass subobjects::

  extension A {
    init fromString(s: String) {
      self.init(Int(s)) // peer delegation to init(Int)
    }
  }

One cannot access any of the instance variables of ``self`` nor invoke
any instance methods on ``self`` before delegating to the peer
initializer, because the object has not yet been
constructed. Additionally, one cannot initialize the instance
variables of ``self``, prior to delegating to the peer, because doing
so would lead to double initializations.

Peer delegation is always a direct call to the named initializer, and
always calls an initializer defined for the same type as the
delegating initializer. Despite the syntactic similarities, this is
very different from Objective-C's ``[self init...]``, which can call
methods in either the superclass or subclass.

Peer delegation is primarily useful when providing convenience
initializers without having to duplicate initialization code. However,
peer delegation is also the only viable way to implement an
initializer for a type within an extension that resides in a different
resilience domain than the definition of the type itself. For example,
consider the following extension of ``A``::

  extension A {
    init(i: Int, j: Int) {
      x = i + j    // initialize x
    }
  }

If this extension is in a different resilience domain than the
definition of ``A``, there is no way to ensure that this initializer
is initializing all of the instance variables of ``A``: new instance
variables could be added to ``A`` in a future version (these would not
be properly initialized) and existing instance variables could become
computed properties (these would be initialized when they shouldn't
be).

Initializer Inheritance
-----------------------
Initializers are *not* inherited by default. Each subclass takes
responsibility for its own initialization by declaring the
initializers one can use to create it. To make a superclass's
initializer available in a subclass, one can re-declare the
initializer and then use superclass delegation to call it::

  class C : A {
    var value = "Hello"

    init(x: Int) {
      super.init(x) // superclass delegation
    }
  }

Although ``C``'s initializer has the same parameters as ``A``'s
initializer, it does not "override" ``A``'s initializer because there
is no dynamic dispatch for initializers (but see below).

We could syntax-optimize initializer inheritance if this becomes
onerous. DaveA provides a reasonable suggestion::

  class C : A {
    var value = "Hello"

    @inherit init(Int)
  }

*Note*: one can only inherit an initializer into a class ``C`` if all
of the instance variables in that class have in-class initializers.

Virtual Initializers
--------------------
The initializer model above only safely permits initialization when we
statically know the type of the complete object being initialized. For
example, this permits the construction ``A(5)`` but not the
following::

  func createAnA(_ aClass: A.metatype) -> A {
    return aClass(5) // error: no complete initializer accepting an ``Int``
  }

The issue here is that, while ``A`` has an initializer accepting an
``Int``, it's not guaranteed that an arbitrary subclass of ``A`` will
have such an initializer. Even if we had that guarantee, there
wouldn't necessarily be any way to call the initializer, because (as
noted above), there is no dynamic dispatch for initializers.

This is an unacceptable limitation for a few reasons. The most obvious
reason is that ``NSCoding`` depends on dynamic dispatch to
``-initWithCoder:`` to deserialize an object of a class type that is
dynamically determined, and Swift classes must safely support this
paradigm. To address this limitation, we can add the ``virtual``
attribute to turn an initializer into a virtual initializer::

  class A {
    @virtual init(x: Int) { ... }
  }

Virtual initializers can be invoked when constructing an object using
an arbitrary value of metatype type (as in the ``createAnA`` example
above), using dynamic dispatch. Therefore, we need to ensure that a
virtual initializer is always a complete object initializer, which
requires that every subclass provide a definition for each virtual
initializer defined in its superclass. For example, the following
class definition would be ill-formed::

  class D : A {
    var floating: Double
  }

because ``D`` does not provide an initializer accepting an ``Int``. To
address this issue, one would add::

  class D : A {
    var floating: Double

    @virtual init(x: Int) {
      floating = 3.14159
      super.init(x)
    }
  }

As a convenience, the compiler could synthesize virtual initializer
definitions when all of the instance variables in the subclass have
in-class initializers::

  class D2 : A {
    var floating = 3.14159

    /* compiler-synthesized */
    @virtual init(x: Int) {
      super.init(x)
    }
  }

This looks a lot like inherited initializers, and can eliminate some
boilerplate for simple subclasses. The primary downside is that the
synthesized implementation might not be the right one, e.g., it will
almost surely be wrong for an inherited ``-initWithCoder:``. I don't
think this is worth doing.

*Note*: as a somewhat unfortunate side effect of the terminology, the
initializers for structs and enums are considered to be virtual,
because they are guaranteed to be complete object initializers. If
this bothers us, we could use the term (and attribute) "complete"
instead of "virtual". I'd prefer to stick with "virtual" and accept
the corner case.

Initializers in Protocols
-------------------------
We currently ban initializers in protocols because we didn't have an
implementation model for them. Protocols, whether used via generics or
via existentials, use dynamic dispatch through the witness table. More
importantly, one of the important aspects of protocols is that, when a
given class ``A`` conforms to a protocol ``P``, all of the subclasses
of ``A`` also conform to ``P``. This property interacts directly with
initializers::

  protocol NSCoding {
    init withCoder(coder: NSCoder)
  }

  class A : NSCoding {
    init withCoder(coder: NSCoder) { /* ... */ }
  }

  class B : A {
    // conforms to NSCoding?
  }

Here, ``A`` appears to conform to ``NSCoding`` because it provides a
matching initializer. ``B`` should conform to ``NSCoding``, because it
should inherit its conformance from ``A``, but the lack of an
``initWithCoder:`` initializer causes problems. The fix here is to
require that the witness be a virtual initializer, which guarantees
that all of the subclasses will have the same initializer. Thus, the
definition of ``A`` above will be ill-formed unless ``initWithCoder:``
is made virtual::

  protocol NSCoding {
    init withCoder(coder: NSCoder)
  }

  class A : NSCoding {
    @virtual init withCoder(coder: NSCoder) { /* ... */ }
  }

  class B : A {
    // either error (due to missing initWithCoder) or synthesized initWithCoder:
  }

As noted earlier, the initializers of structs and enums are considered
virtual.

Objective-C Interoperability
----------------------------
The initialization model described above guarantees that objects are
properly initialized before they are used, covering all of the major
use cases for initialization while maintaining soundness. Objective-C
has a very different initialization model with which Swift must
interoperate.

Objective-C Entrypoints
~~~~~~~~~~~~~~~~~~~~~~~
Each Swift initializer definition produces a corresponding Objective-C
init method. The existence of this init method allows object
construction from Objective-C (both directly via ``[[A alloc]
init:5]`` and indirectly via, e.g., ``[obj initWithCoder:coder]``)
and initialization of the superclass subobject when an Objective-C class
inherits from a Swift class (e.g., ``[super initWithCoder:coder]``).

Note that, while Swift's initializers are not inherited and cannot
override, this is only true *in Swift code*. If a subclass defines an
initializer with the same Objective-C selector as an initializer in
its superclass, the Objective-C init method produced for the former
will override the Objective-C init method produced for the
latter.

Objective-C Restrictions
~~~~~~~~~~~~~~~~~~~~~~~~
The emission of Objective-C init methods for Swift initializers open
up a few soundness problems, illustrated here::

  @interface A
  @end

  @implementation A
  - init {
    return [self initWithInt:5];
  }

  - initWithInt:(int)x {
    // initialize me
  }

  - initWithString:(NSString *)s {
    // initialize me
  }
  @end

  class B1 : A {
    var dict: NSDictionary

    init withInt(x: Int) {
      dict = []
      super.init() // loops forever, initializing dict repeatedly
    }
  }

  class B2 : A {
  }

  @interface C : B2
  @end

  @implementation C
  @end

  void getCFromString(NSString *str) {
    return [C initWithString:str]; // doesn't initialize B's dict ivar
  }

The first problem, with ``B1``, comes from ``A``'s dispatched
delegation to ``-initWithInt:``, which is overridden by ``B1``'s
initializer with the same selector. We can address this problem by
enforcing that superclass delegation to an Objective-C superclass
initializer refer to a designated initializer of that superclass when
that class has at least one initializer marked as a designated
initializer.

The second problem, with ``C``, comes from Objective-C's implicit
inheritance of initializers. We can address this problem by specifying
that init methods in Objective-C are never visible through Swift
classes, making the message send ``[C initWithString:str]``
ill-formed. This is a relatively small Clang-side change.

Remaining Soundness Holes
~~~~~~~~~~~~~~~~~~~~~~~~~
Neither of the above "fixes" are complete. The first depends entirely
on the adoption of a not-yet-implemented Clang attribute to mark the
designated initializers for Objective-C classes, while the second is
(almost trivially) defeated by passing the ``-initWithString:``
message to an object of type ``id`` or using some other dynamic
reflection.

If we want to close these holes tighter, we could stop emitting
Objective-C init methods for Swift initializers. Instead, we would
fake the init method declarations when importing Swift modules into
Clang, and teach Clang's CodeGen to emit calls directly to the Swift
initializers. It would still not be perfect (e.g., some variant of the
problem with ``C`` would persist), but it would be closer. I suspect
that this is far more work than it is worth, and that the "fixes"
described above are sufficient.
