Swift Language Optionals Optional Chaining


You can use Optional Chaining in order to call a method, access a property or subscript an optional. This is done by placing a ? between the given optional variable and the given member (method, property or subscript).

struct Foo {
    func doSomething() {
        print("Hello World!")

var foo : Foo? = Foo()

foo?.doSomething() // prints "Hello World!" as foo is non-nil

If foo contains a value, doSomething() will be called on it. If foo is nil, then nothing bad will happen – the code will simply fail silently and continue executing.

var foo : Foo? = nil

foo?.doSomething() // will not be called as foo is nil

(This is similar behaviour to sending messages to nil in Objective-C)

The reason that Optional Chaining is named as such is because ‘optionality’ will be propagated through the members you call/access. What this means is that the return values of any members used with optional chaining will be optional, regardless of whether they are typed as optional or not.

struct Foo {
    var bar : Int
    func doSomething() { ... }

let foo : Foo? = Foo(bar: 5)
print(foo?.bar) // Optional(5)

Here foo?.bar is returning an Int? even though bar is non-optional, as foo itself is optional.

As optionality is propagated, methods returning Void will return Void? when called with optional chaining. This can be useful in order to determine whether the method was called or not (and therefore if the optional has a value).

let foo : Foo? = Foo()

if foo?.doSomething() != nil {
    print("foo is non-nil, and doSomething() was called")
} else {
    print("foo is nil, therefore doSomething() wasn't called")

Here we’re comparing the Void? return value with nil in order to determine whether the method was called (and therefore whether foo is non-nil).