Difference between Force Unwrapping Optionals and Implicitly Unwrapped Optionals
First of all let's define an Optional
An Optional value is a container of some type (Int
, String
, UIColor
, ...), it could contain the value (1
, "Hello world"
, .greenColor()
, ...) or nil
.
let anOptionalInt: Int? = 1
let anotherOptionalInt: Int? = nil
When in Swift we see an Optional value we think:
Ok this could contain the actual value or
nil
Force unwrapping
It's the action of extracting the value contained inside an Optional
.
This operation is dangerous because you are telling the compiler: I am sure this Optional value does contain a real value, extract it!
let anOptionalInt: Int? = 1
let anInt: Int = anOptionalInt!
Now anInt
contains the value 1.
If we perform a force unwrapping on an Optional value that happens to contain nil
we get a fatalError
, the app does crash and there is no way to recover it.
let anotherOptionalInt: Int? = nil
let anotherInt = anotherOptionalInt!
fatal error: unexpectedly found nil while unwrapping an Optional value
Implicitly unwrapped optionals
When we define an Implicitly unwrapped optional, we define a container that will automatically perform a force unwrap each time we read it.
var text: String! = "Hello"
If now we read text
let name = text
we don't get an Optional String
but a plain String
because text
automatically unwrapped it's content.
However text is still an optional so we can put a nil
value inside it
text = nil
But as soon as we read it (and it contains nil
) we get a fatal error because we are unwrapping an optional containing nil
let anotherName = text
fatal error: unexpectedly found nil while unwrapping an Optional value
I'd say no, you're drawing a false distinction:
The first half is right; unwrapping is certainly something you do to Optionals, and forced unwrapping is a way to do it (an unsafe way).
But as to what an implicitly unwrapped Optional is: it is a way of marking an Optional type so that forced unwrapping will be done for you (if you use the Optional in a place where it can't be used, but could be used if it were unwrapped).
An implicitly unwrapped optional is a normal optional behind the scenes, but can also be used like a non optional value, so yes you are correct.
But if you declare a value as implicitly unwrapped, it is equivalent to force unwrapping it at every use.
For Implicitly unwrapped Optionals there are 4 main reasons to do that.
1: A Constant That Cannot Be Defined During Initialization
2: Interacting with an Objective-C API
3: When Your App Cannot Recover From a Variable Being nil
4: NSObject
Initializers