Depending upon your language of choice this kind of thing usually results in an NPE or the abrupt termination of your program, but in Objective-C nothing happens.

The reason nothing happens in Objective-C is because the semantics of sending a message to nil are well defined.

If you send a message which returns nothing, i.e., void, nothing happens.

if you send a message which returns a reference to object to nil then you get back nil.

If you send a message which returns something other than an object to nil you get back 0 or its equivalent

In the example above the call to lastPathComponent on nil returns nil.

The call to hasSuffix on nil returns false.

The downside to this is that you can, on occasion, spend quite a bit of time wondering why nothing is happening only to eventually discover that some variable had the value nil when it ought not to have.

The designers of Swift have decided to be helpful and eliminate this downside by making it both impossible to forget to initialize variables and impossible to initialize them to nil in the Objective-C style.

1.0 Constants And Variables

You can declare a constant in Swift like this

let constantCod: String = "a fish"

Swift supports type inference so you can omit the type if you wish

let constantCod = "a fish"

As you might expect given that it is a constant you cannot assign another value to constantCod once it has been initialized.

In addition if the constant refers to a compound value, an instance of a struct for example, the value itself is immutable.

You declare a variable in Swift in the same way but using var instead of let.

var cod: String = "a fish"

and without the type.

var cod = "a fish"

You can assign another value to a variable in the usual way

cod = "another fish"

If you are declaring a constant or a global variable you must specify a value in the declaration, but if you are declaring a local variable you can omit the initializer if you wish in which case you must specify the type.

If you declare a local variable without an inititializer you cannot access that variable until it has been explicitly initialized.

Given that the type of the expression is of type Optional<T> you might think that if you want to call a method on the result you need to use the ‘?’ suffix again like so

path?.componentsSeparatedByString("/")?.reverse()

but if you try this you get a compiler error, specifically

path?.componentsSeparatedByString("/")?.reverse()

Operand of postfix '?' should have optional type: type is 'String[]'

which is a bit puzzling at first.

In fact while it is true that in isolation the type of

path?.componentsSeparatedByString("/")

is

Optional<String[]>

in the context of a chain of method calls if the Optional variable has no value then the ? operator shortcuts the entire chain and returns immediately.

So at runtime at the point the method reverse is being called the ? operator has already opened the box and found aString[] value in it rather than nil and it has called componentsSeparatedByString on it and the type of

path?.componentsSeparatedByString("/")

really is

String[]

Another way of looking at it is that adding a postfix ? is equivalent to doing this

from which it is clear that the result of calling componentsSeparatedByString really is a String[].

Which is all a very long and round about way of you do not actually need the second postfix ? at all. You can simply do this

path?.componentsSeparatedByString("/").reverse()

You can chain as many methods together as you can find and you still only need the initial ‘?’ assuming of course that none of the methods themselves explicitly return Optional values.

If the last method in the chain returns a value of type Optional<T>, for example

path?.componentsSeparatedByString("/").reverse()[0].toInt()

where the method toInt returns

Optional<Int>

you might think that the result of the method chain expression would be

Optional<Optional<T>>

but it is in fact

Optional<T>

which has the merit of consistency and simplicity since you only ever have to unwrap the resulting value once

4.5 Implicit Unwrapping

If you declare an Optional variable then, as we have seen, you need to unwrap it one way or another each time you want to use the value.

If you are in a position where you are certain that the Optional variable will definitely have a value each time you use it then you can avoid the need to explicitly unwrap it at each point of use
by declaring it like this

var optionalDab: String!

adding a postfix exclamation mark (!) to the type rather than a question mark (?).

You can then refer to it directly when using without explicitly unwrapping it.

It is still being unwrapped implicitly using forced unwrapping so if your model of the variable’s usage is incorrect and there is in fact some point at which it can be used before it has been initialized you will find out all about it at runtime.

5.0 Optional Constants

You can, if you want, declare constants with Optional types but after the novelty has worn off they turn out not to be very interesting at all.

Since the only thing you can do with a constant is initialize it or use it you can either have a constant which is guaranteed to be nil

let constantDab: String?

or one that is guaranteed to have a value

let constantDab: String? = "an optional fish"

and thats it.

6.0 Optional Globals

You can declare a global variable with an Optional value.

This can be useful if you do not want to or cannot initialize it at the point it is declared but it is guaranteed to have been initialized before it is used.

This case also allows you to take advantage of implicit unwrapping as described above but the caveat about runtime exceptions also applies.