Safe calls(?.) vs Nil checks(!.) in Swift
In Swift, the type system distinguishes between references that can hold nil (nil references) and those that can not (non-nil references).
For example, a normal property can’t hold a nil value and will show a compile error.
This post was originally posted at https://agrawalsuneet.github.io/blogs/safe-calls-vs-nil-checks-in-swift/ and later reposted on Medium.
Instead, we can add a ? after the data type of that property which declares that variable as a nillable property.
var nillableVariable : CustomClass? = CustomClass()
nillableVariable = nil //works fine
In any case, the nillable property requires a nil check every time before accessing that property or requires a confirmation from the developer that the estimation of that property won’t be nil while accessing it.
variable.someMethodCall() //works fine as the compiler is sure that
//the variable can’t be nil
nillableVariable.someMethodCall() //will highlight compilation error
//as compiler is not sure as
//nilVariable can be nil.
There are still few techniques for using or accessing the nillable variable. One of them is safe call ?. and another one is nil check !. but before figuring out the difference among both, let’s understand what they are in detail first.
If Let and Guard Let
This is the old pattern that we use in every other language, checking the variable if its nil or not.
If let checks if the nillable variable is nil or not.
If the variable is nil, this will go to else block.
If not, it will copy the non-nil reference into another variable within its scope where we can use it without any nil checks.
if let nillableVariable = nillableVariable {
nillableVariable.someMethodCall()
} else {
// fallback flow
}
Guard let separates the failure case first. It is designed to exit the current function, loop or condition if the check fails.
It is used to run a code block and return if the variable is nil otherwise below else condition, the variable is non-nil and we can use it without any nil checks.
guard let nillableVariable = nillableVariable else {
//do something in nil case
return
}
nillableVariable.someMethodCall()
You can read the difference between if-let and guard-let on if vs if let vs guard let in Swift.