You might occasionally find it convenient to use implicit unwrapping when declaring @IBOutlet properties, or in other places where you know you won’t access a value until it has been fully initialized. However, you are usually better off avoiding implicit unwrapping and should use explicit unwrapping through if let and guard let. When you’re certain it’s safe, use explicit force-unwrapping via !.
The @IBOutlet part confused me a bit.
Are you saying this pattern should not be used? @IBOutlet weak var tableView: UITableView!
@IBOutlet is just used as an example of where you might find it convenient to use an implicitly unwrapped optional. What I was trying to get across is that although there may be some specific cases where you may want to use implicit unwrapping as a tool, it shouldn't be the tool of choice in most circumstances.
For example I cannot think of a case where I would recommend writing a Swift method that has implicitly unwrapped optionals in its parameter list, despite that being one of the places where they are still allowed. You will of course sometimes see Objective-C methods that get imported with parameter lists that include implicitly unwrapped optionals because that is what we default to for nullable types in methods that have not been audited for nullability.
What I would generally discourage is the use of implicitly unwrapped optionals as a general strategy to circumvent the rules around initializing class properties. I'm not sure how common that practice is, but I have seen projects where every property of every class is declared as implicitly unwrapped for this reason.
Note that the result of AnyObject lookup is treated as an optional that is implicitly unwrapped. If you lookup a property that itself is also declared as implicitly unwrapped, the expression now has two levels of implicit unwrapping.
What is meant by "AnyObject lookup"? The blog post contains the following example code:
func getLabel(object: AnyObject) -> UILabel {
return object.property // forces both optionals, resulting in a UILabel
}
But that doesn't work, right? As far as I know, AnyObject doesn't have a property with the name "property" and it can't be extended either.
FWIW, in the last year, I've seen developers coming from other experience making all class properties: var name: String!
My conclusions why are:
They don't understand initializer chaining
They feel like it's to much boilerplate for initializer chaining
Would love an auto-synthesized init for all properties as an overridable convenience
They don't want to use guard let or if let
Not saying I think this makes sense not to learn the patterns
Initializer chaining not available
On the last point, @IBOutlet weak var tableView: UITableView! being a correct pattern in ViewControllers leads the less experienced to believe that's the right thing always. Then that mis-learning gets propagated to code that definitely doesn't need it.
In short, AnyObject works somewhat like id in ObjC; you can send it any method known to be defined on any ObjC class. It's a concession to ObjC interoperability, one that is rarely actually needed.
Does this fix the case where implicitly unwrapped optionals and optionals don't play nice in a protocol?
eg:
protocol TextEntryView {
var text: String?
}
// This works.
class UITextField: TextEntryView {}
// This doesn't work because it's declaration has `text: String!`
class UITextView: TextEntryView {}
This is a slight problem which I found frustrating from a dev perspective. In my mind implicitly unwrapped optionals should have the same conformance behaviour as optionals when it comes to protocol adherence.