Unwrapping
In the previous articles we looked at unwrapping the optionals forcibly. This is done by using the ! operator on the optional variable at the point of its use.
var name: String?
name = “San Francisco”
print(“City is \(name)”)
// Prints: City is Optional(“San Francisco”)
print(“City is \(name!)”)
// Prints: City is San Francisco
In the code above, when we printed out name (by using string interpolation with surrounding string), it prints out Optional(“San Francisco”). This is because the variable name is an Optional. When we forcibly unwrapped it, we can see the actual String come out of it rather than the Optional. Various uses have been discussed in the previous articles.
Now let’s talk about a way of automatically/implicitly unwrapping an optional.
Implicit Unwrapping
Instead of unwrapping each time where an optional is used, with the following approach the unwrapped value is provided.
var name: String!
name = “San Francisco”
print(“City is \(name)”)
// Prints: City is San Francisco
Here the exclamation point (!) is used on the type at the time of declaration. Then when you use name at a later point (at perhaps the multiple places where this might be used), it doesn’t need to be unwrapped. There is no need to add ! at all those places.
Variables defined like this can still hold a nil value.
var name: String!
print(“City is \(name)”)
// Prints: City is nil
name = “San Francisco”
print(“City is \(name)”)
// Prints: City is San Francisco
name = nil
print(“City is \(name)”)
// Prints: City is nil
As you can see, right after the declaration, name contains a nil value. Then it was assigned to a String literal. Then back to nil.
Problems with Implicit Unwrapping
The implicit unwrapping suffers from the same problems with the nil value that we discussed during the forced unwrapping with the ! operator.
var name: String!
name = “San Francisco”
var displayString = “City is “ + name
print(displayString)
// Prints: City is San Francisco
name = nil
var displayString2 = “Welcome to “ + name
// Crash: there is nil when name is unwrapped
As long as there a non-nil value in this implicitly unwrapped variable, we are fine when we use it operations. However, once the value becomes nil (no-value) we will run into the same problems as with forced unwrapping.
Why do we need Implicit Unwrapping?
Apart from saving a little bit of typing when a variable is unwrapped, why do we need this implicit unwrapping. If we know that the there is going to be a valid non-nil value in the variable, why can’t we declare it as a non-optional? Why do we need either a question mark (?) or an exclamation mark (!) at the end of the type in this scenario or any other scenario?
This is useful when the following situation occurs:
- We don’t have the value of a variable at the declaration - hence it needs to an optional
- But we will get a proper value some time after the initial declaration/initialization
- When are ready to use it, that value must be there — otherwise we can’t proceed
These scenarios occur not very often in the regular programming. There is one place this pattern is consistently used — developing user interface with the help of story boards or xib files.
In a typical app development scenario, you would draw out the user interface in a story board. A given view controller might contain buttons, labels, text fields, etc. And then you would Control-drag from these views into the code and thus creating outlets.
When an instance of this class is initialized, Swift doesn’t have the properly initialized objects to associate with these outlets. Hence they will be set to nil. Once the objects drawn in the story board are fully initialized those values will be assigned to these outlet variables.
And at the time of using these variables, there is no point proceeding any further if these objects are still nil for some reason. Generally though they will be ready to be used and hence they can be implicitly unwrapped. So the above situation of using ! at the end of Type fits perfectly here.
Implicit Unwrapping in User Interface Creation
Let’s say you have created 3 controls on view controller in a story board:
- name - a label
- name - a text field to get the name
- save - a button to save the info
In the view controller code you will create the following outlet variables and connect them to the above controls in the story board.
@IBOutlet var nameLabel: UILabel!
@IBOutlet var nameTextField: UITextField!
@IBOutlet var saveButton: UIButton!
As you can see above, these outlets are to automatically unwrapped: UILabel!, UITextField!, UIButton!. So, when they are initialized, their values will be nil. Since they are connected to the controls drawn in the story board fully initialized valid objects of UILabel, UITextField, and UIButton will be assigned to them.
If you want to change their properties down below (different titles, different colors, etc., for example), then at that point you want them to be ready and available - not nil values. Since they are automatically unwrapped, there is less code, but there will also be a failure if they weren’t initialized to non-nil values. That’s what you want, because there is no point in proceeding if the user interface objects are nil.
You can also use this implicit unwrapping in cases similar to above. Let’s say you don’t have the value for a certain user related information at the time of initialization, but then you would get it from the database over the Internet. And you will start using that valid value in the code at a later point and it must be available at that point. Generally code can be structured to avoid this scenario. So, most of the time you would just be using this in the UI code described above.