Last week, I wrote about weak and strong outlets. But there's another question about outlets that comes up frequently. Should outlets be declared as optionals or implicitly unwrapped optionals? This tutorial zooms in on the pros and cons of each of these options.

What Does Apple Recommend

Last week, we first explored what Apple recommends by creating a project in Xcode and that's a good place to start. Launch Xcode and create a new project. Choose the Single View Application template and name the project Outlets.

Should Outlets Be Optionals or Implicitly Unwrapped Optionals

Open Main.storyboard, bring up the Object Library on the right, and add a label to the View Controller Scene.

Add a Label to the View Controller Scene

Press Option and click ViewController.swift in the Project Navigator to open the Assistant Editor. Create an outlet by pressing Control and dragging from the UILabel instance in the View Controller Scene to ViewController.swift in the Assistant Editor on the right.

Create an Outlet for the Label

Name the outlet label and click Create to have Xcode create the outlet.

Create an Outlet for the Label

If you've read last week's tutorial, then it shouldn't surprise you that the outlet is declared strong, not weak. What's of special interest to us is the type of the outlet, UILabel!. The outlet is declared as an implicitly unwrapped optional, not an optional. Remember that the @IBOutlet Interface Builder attribute indicates the property is an outlet.

@IBOutlet var label: UILabel!

What Is the Difference Between Optionals and Implicitly Unwrapped Optionals

Before we continue our discussion about outlets, it's important to understand what the difference is between optionals and implicitly unwrapped optionals. The difference is obvious thanks to Swift's expressive syntax. Under the hood, an implicitly unwrapped optional is an optional. But the exclamation mark in the property declaration unmistakably indicates that we're taking a risk. Whenever you encounter an exclamation mark, you need to be on guard.

You probably know that an optional has a value or it doesn't. Plain and simple. The reason many developers are not fond of optionals is because you cannot directly access the value of an optional. To safely access the value of an optional, you need to unwrap it. Optional binding is a construct that lets you safely access the optional's value.

var message: String? = "Hello, World"

if let message = message {
    print(message)
}

If you're absolutely certain an optional contains a value, you can take a shortcut by force unwrapping the value stored in the optional. To force unwrap an optional, we append an exclamation mark to the name of the variable or constant. Congratulations. You've saved yourself an if statement and two lines of code. But is this worth the risk? That's the question you always need to ask yourself when using the exclamation mark in Swift.

var message: String? = "Hello, World"

print(message!)

The exclamation mark warns us that we're taking a risk. We're about to perform an operation that can backfire. If message doesn't have a value, a fatal error is thrown and the application terminates immediately. That's the risk you're taking.

Convenience Over Safety

Implicitly Unwrapped Optionals Are Convenient

Why would you want to use an implicitly unwrapped optional? The answer is very simple. Clarity and convenience. Most developers use implicitly unwrapped optionals because it's convenient. But it's worth mentioning that implicitly unwrapped optionals can also bring clarity to your code by eliminating the need for optional binding and optional chaining.

The value of the label outlet we declared earlier in the ViewController class can be accessed like any other variable. That's only possible because we declared label as an implicitly unwrapped optional.

Be warned, though, if you forget to connect the label outlet in Interface Builder and you access the label property in the ViewController class, your application crashes due to a fatal error the application cannot recover from. That's the risk you're taking. But there's more.

Optionals Are Safe

If you don't like risks, then declaring an outlet as optional is the safest option. Period. The downside is that you need to work with an optional. To access the value stored in the optional, you need to safely unwrap it. If you want to take a shortcut by force unwrapping the optional, then you might as well have declared the outlet as an implicitly unwrapped optional in the first place.

Why Are Outlets Declared as Optionals

Have you ever wondered why outlets are declared as optionals or implicitly unwrapped optionals? The reason is simple. Before an instance of a class or structure finishes initialization, every stored property needs to have a valid value.

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state. — The Swift Programming Language

If you don't know what value a stored property should have during initialization, then you can assign a default value or you can declare the property as an (implicitly unwrapped) optional. And that brings us to the reason why outlets are declared as (implicitly unwrapped) optionals.

The value of an outlet cannot be set during initialization. Let's revisit the project we created earlier. When the view controller is instantiated, its view hasn't been loaded yet. It's only after the view controller is initialized that it loads its view. This also means that any outlets declared in the view controller class don't have a value immediately after the view controller's initialization. That's why an outlet is always declared as an (implicitly unwrapped) optional.

What Are the Risks

With the above in mind, you should now understand what the risks are when you declare an outlet as an implicitly unwrapped optional. If you forget to connect an outlet in Interface Builder, then your application crashes when the outlet is accessed. But that isn't the most important risk. This is easy to fix in development and should never happen in production. If you've properly tested your application, your application won't suffer from this type of problem.

The most important risks have to do with accessing an outlet before its value is set. If you access an outlet before or while the view controller loads its view, you can run into a runtime error.

It's important to remember that you're taking a risk every time you use an implicitly unwrapped optional. Because of the potential risk involved, some developers avoid using implicitly unwrapped optionals for outlets. It's the safest option, but it comes with some overhead.

While I see the benefit of using optionals instead of implicitly unwrapped optionals, I always declare outlets as implicitly unwrapped optionals, the reason being clarity and convenience.

When Not to Use an Implicitly Unwrapped Optional

I hope it's clear that any property, including outlets, that can become nil during the lifetime of the object that owns it, should never be declared as an implicitly unwrapped optional.