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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…