Alternative 1: Force unwrap non-optional dependencies
- No need no use any methods to unwrap on each usage, unless there are cases you anticipate a value to be nil.
var value: String!
value = "Hi"
print(value.count)
- A crash is a clear signal which may help with debugging by signalling a value was not set which should have been.
var greeting: String!
print(greeting.count)
produces:
__lldb_expr_17/Crash.playground:4: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
-
Greater than 0% risk of a runtime crash on production for now and for future developers.
- If the value is set to nil.
var greeting: String! = "hi" greeting = nil print(greeting.count)
- If the value is dereferenced (This can happen even in some cases with IBOutlets labeled
weak
which is why you always want them strong).
@IBOutlet weak var label: UILabel! ... print(label.text) // <crash due to label being dereferenced.
- If the assignment of a value is moved to a later point after a read would occur.
var greeting: String! print(greeting.count) greeting = "Hi!" // moved from line 2
- If a read is placed before the assignment of the value.
var greeting: String! print(greeting.count) // moved from line 3 greeting = "Hi!"
-
Appears accidental and can confuse developers.
var greeting: String! // Hmm... Did they intend to force unwrap? Did they look at all the considerations? print(greeting.count) greeting = "Hi!"
-
The type system will allow other developers to use it as though it has 0% chance of being nil, thus it:
otherLabel.text = "\(greeting.count)" // You or me. ... var greeting: String! // Surprise! `greeting` isn't assured to be non-nil.
-
Requires future developers to identify threats and permutations to gain assurances that a crash does not occcur in production.
var greeting: String! // Oh, boy, I need to work with this property.. but I need to study all the possible risks and permutations of when this could be nil so that I don't introduce a crash just by using it.
-
Doesn't show where a property or variable wasn't assigned a value but should have been, nor where it was dereferenced, nor when it was assigned to nil.
var greeting: String!
print(greeting.count)
produces:
__lldb_expr_17/Crash.playground:4: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
But that ^ doesn't tell me where the value should have been assigned, nor where it was dereferenced, nor when it was assigned to nil. Which is the bulk of the work for debugging this kind of issue.
- There are alternatives. For example:
if money == nil {
fatalAssertion("money should never be nil. We need to crash here to prevent a transaction which might not be supported).
}
Has intentionality and doesn't confuse other developers.
- Usage for force unwrap sometimes encourages force unwrap for other times.
var greeting: String!
Hey someone used force unwrap... Thats easy!
var myGreeting: String!