When should you use implicitly unwrapped optionals? The short answer to this question is "Never." But the answer is more nuanced than that. Implicitly unwrapped optionals were added to the Swift language for a reason.
What Is an Implicitly Unwrapped Optional?
The concept underlying implicitly unwrapped optionals is easy to understand. As the name implies, an implicitly unwrapped optional behaves as an optional. I write behave because optionals and implicitly unwrapped optionals are defined differently in the Swift standard library. What's important is that an implicitly unwrapped optional is allowed to have no value. It shares this trait with optionals.
We declare an implicitly unwrapped optional by appending an exclamation mark to the type.
var text: String!
Remember that the exclamation mark is a warning sign in Swift. It indicates that we can access the value of the implicitly unwrapped optional without unwrapping it using optional binding or optional chaining.
I need to mention that we can still use optional binding and optional chaining to safely access the value of the implicitly unwrapped optional.
var text: String!
if let text = text {
...
}
var text: String!
let startIndex = text?.startIndex
We can also check it for nil
. But this shouldn't be necessary since an implicitly unwrapped optional promises the compiler it has a value when it is accessed.
var text: String!
if text == nil {
...
}
You could see an implicitly unwrapped optional as an optional whose value is always accessed by forced unwrapping. This also means that a runtime error is thrown if you access an implicitly unwrapped optional that has no value.
Why Would I Need Implicitly Unwrapped Optionals?
Like I said, it is perfectly fine and possible to never use implicitly unwrapped optionals. Implicitly unwrapped optionals are a compromise between safety and convenience. Whenever you use an implicitly unwrapped optional instead of an optional, you trade safety for convenience. If safety is more important to you, then don't use implicitly unwrapped optionals.
Implicitly unwrapped optionals are a compromise between safety and convenience.
If you declare a property as optional, then you need to use optional binding or optional chaining every time you access the value of the optional. While this isn't a problem, it makes the code you write more verbose and the result may be less readable. This isn't true if you use implicitly unwrapped optionals.
When Should You Use Implicitly Unwrapped Optionals?
The Swift Programming Language states the following.
Sometimes it is clear from a program's structure that an optional will always have a value, after the value is first set. In these cases, it is useful to remove the need to check and unwrap the optional's value every time it is accessed, because it can be safely assumed to have a value all of the time. - The Swift Programming Language
Outlets are a common example when discussing implicitly unwrapped optionals. Why does Apple use implicitly unwrapped optionals to declare outlets? The reason is simple.
Every stored property of a class needs to have a valid value before the initialization of the instance is complete. If you don’t know the value of a stored property during initialization, you can assign a sensible default value or declare it as an optional, which has a default value of nil
. But there is a third option, use an implicitly unwrapped optional.
The value of an outlet is set after the instance of the class is initialized. This is inconvenient since you know that the outlet will have a valid value when it is later accessed. For these reasons, outlets are often declared as implicitly unwrapped optionals. The only reason for doing so is convenience. That is important to understand. It is perfectly fine to declare outlets as optionals.
import UIKit
class ViewController: UIViewController {
@IBOutlet var titleLabel: UILabel!
...
}
Being Bitten by Implicitly Unwrapped Optionals
If you use implicitly unwrapped optionals for anything else but outlets, I can assure you that you will be bitten at some point. When I first started working with Swift, I noticed (looking back) how easily implicitly unwrapped optionals made their way into my code. These implicitly unwrapped optionals were always properties that I couldn't give a value during initialization. This is a common issue when working with storyboards and segues, for example.
A few months ago, I took over a project that makes ample use of implicitly unwrapped optionals and that has backfired several times since I started working on the project. While I can appreciate the above statement in The Swift Programming Language, it may be obvious that an optional will always have a value when you write the code ... but code changes and assumptions change.
Someone might take over the project and not know about the assumptions you made when you wrote the code that uses implicitly unwrapped optionals.
Be Careful
I continue to declare outlets as implicitly unwrapped optionals, but I never use implicitly unwrapped optionals for anything else. Be careful when you make assumptions or promises you may not be able to keep. The code you write today won't look the same a year from now.
Don't try to bypass Swift's type safety. It is a cornerstone of the language and that is for good reason. Implicitly unwrapped optionals were added to the language for convenience, but that problem can also be solved with optionals.