Difference between Force Unwrapping Optionals and Implicitly Unwrapped Optionals
Asked Answered
G

4

29

I was very confused about forced unwrapping and implicit unwrapping at first. Now, the following understanding comes from my self-study:

There is no action available for implicit unwrapping, but there is something called implicitly unwrapped Optionals. Implicitly unwrapped Optionals and normal Optionals are both Optionals, the difference being when accessing an implicitly unwrapped Optional, you confidently know that there is a valid value under the hood and ready for use. Normal Optionals need if let binding or a forced unwrapping (!) action to access the possible values behind the optional variables.

Summary:

Forced unwrapping is an action done on the normal Optionals.

Implicitly unwrapped Optionals are Optionals, usually used for class initialization and will pass values without exclamation mark when used.

Question:

Am I right? If my understanding is not precise, I would appreciate it if you correct me.

Thanks

Gunar answered 7/8, 2016 at 18:59 Comment(3)
If you declare a value as implicitly unwrapped, it is equivalent to force unwrapping it at every use site.Titty
@Titty so it will save you some time, since there is no need to add the exclamation mark every time. Thx ")Gunar
you can check the video, wll explained youtube.com/watch?v=BfWopYE2y4wEulaliaeulaliah
F
92

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

enter image description here

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.

enter image description here

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

enter image description here

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
Floriated answered 7/8, 2016 at 19:27 Comment(4)
Thank you so much for such complete explanationGunar
Thanks for your efforts.Pase
Nice explanation, I just want to point out that forced unwrapping is not dangerous by itself, it's only dangerous when you're dealing with data that can be nil and it's out of your control. On the other hand, if you're talking about just a function that you wrote passing some locally scoped data to another function that you wrote, forced unwrapping in the second function can still produce an error, but that's the kind of "good" error that tells you that you got a bug in your code (because you probably passed the wrong arg).Piled
Great explantationRadiotherapy
D
5

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

Debug answered 7/8, 2016 at 19:13 Comment(2)
Thanks for your help and explanationGunar
2phase initialization especially with UIViewController. I dont understand your last point about NSObject.Neurasthenic
Y
2

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).

Yclept answered 7/8, 2016 at 19:33 Comment(2)
so it is a way / style to create a unique optional, it does not create a new concept optional, it was still an optional but with extra attributes.Gunar
there used to be a distinct type ImplicitlyUnwrappedOptional but now it's just an Optional with this extra power of automatically force-unwrapping itselfYclept
M
0

Implicitly Unwrapping You define an Optional as implicitly unwrapped when you define its type like this.

let unwrappedString: String!

This technique allows you to tell the compiler to automatically unwrap that value as if it wasn't optional at all. Similarly to Type? which is syntactic sugar for Optional, Type! is equivalent to ImplicitlyUnwrappedOptional. A common example of implicitly unwrapped optional is how view controller define their IBOutlets:

@IBOutlet var displayLabel: UILabel! @IBOutlet var actionButton: UIButton!

It makes sense to define the outlets as implicitly unwrapped optional because they are going to be instantiated by Interface Builder. It would be cumbersome to always unwrap each view outlet inside view controllers. Because of their implicitly unwrapped nature, if you forget to connect an outlet to it Interface Builder view an run the app you'll get a runtime error when you try to access it in the view controller.

Monandrous answered 27/5, 2020 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.