Difference Between Force Unwrapping Optionals and Implicitly Unwrapped Optionals

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

Sample Image

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.

Sample Image

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

Sample Image

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

swift - Implicit unwrapped optionals

It's all related to the class initialization.

take Outlets for example they're force unwrapped because we know they will hold a value after initialization from the XIB or Storyboard but they will not be set before the class initialization.

A force unwrapped optional exits to tell the compiler I'm taking the responsibility to make sure this variable will be set before calling it.

in your example I don't think it makes sense to write:

let aString: String! = "this is a test string"

It should just be as you wrote:

let aString: String = "this is a test string"

It makes more sense to have:

var aString: String!

meaning you'll take ownership of this variable initialization (i.e making sure it's not nil)

Difference between optional and forced unwrapping

The String? is normal optional. It can contain either String or nil.

The String! is an implicitly unwrapped optional where you indicate that it will always have a value - after it is initialized.

yourname in your case is an optional, yourname2! isn't.
Your first print statement will output something like "Your name is Optional("Paula")"

Your second print statement will output something like "Your name is John". It will print the same if you remove the exclamation mark from the statement.

By the way, Swift documentation is available as "The Swift Programming Language" for free on iBooks and the very latest is also online here.

Why does a `nil` implicitly unwrapped optional print `nil` and not crash?

That does not crash because print accepts Any as the first parameter. Are implicitly unwrapped optionals a kind of Any? Yes they are! Anything is Any. There is no need to unwrap the optional. An implicitly unwrapped optional can be used in a place where Any is expected without unwrapping the optional.

That could potentially be confusing because now you have something with type Any, which doesn't look like it's optional, but it is an optional under the hood. To avoid this, Swift will output a warning telling you that you are implicitly coercing whatever optional type to Any.

You need to use ! to force unwrap it here:

print(x!)

Why create Implicitly Unwrapped Optionals , since that implies you know there's a value?

Consider the case of an object that may have nil properties while it's being constructed and configured, but is immutable and non-nil afterwards (NSImage is often treated this way, though in its case it's still useful to mutate sometimes). Implicitly unwrapped optionals would clean up its code a good deal, with relatively low loss of safety (as long as the one guarantee held, it would be safe).

(Edit) To be clear though: regular optionals are nearly always preferable.

What is the advantage of force unwrapping an optional?

Performance-wise there might be a very to very very small no difference between forced and optional binding/chaining, as the optional version might have an extra if somewhere.

But nonetheless when talking about performance issues, the performance bottlenecks come from other parts of the code, like non-improved loops, lots of accumulation NSNotification's sent in a short amount of time, unnecessary redraws of the UI, etc.

So it's best to stay on the safer side and use optional binding/casting/chaining and focus on the parts of the code that adds actual performance penalties. Even if at the time you write the code the value is guaranteed to be non-nil, in the future in might be that the conditions will change and you'll suddenly end up with crashes that you didn't expect they'll occur.

Swift has made it very easy to deal with optionals, without writing a lot of boilerplate code, you should take advantage of those features.

Alternative to implicitly unwrapped optional using @propertyWrapper in swift

You can simulate implicitly unwrapped optionals with a property wrapper as follows:

@propertyWrapper
struct MaybeUninitialized<T> {
private var storage: T?
var wrappedValue: T {
get { storage! }
set { storage = newValue}
}
}

Then you can even use possibly uninitialized fields storing optionals without accidentially unwrapping the optional. Something like this:

@MaybeUninitialized var x: Int?

print(x) // will crash
x = nil
print(x) // print nil


Related Topics



Leave a reply



Submit