What's the difference between this:
_ = navigationController?.popViewController(animated: true)
defer {
let rootVC = navigationController?.topViewController as? RootViewVC
rootVC?.openLink(url: url)
}
return
and this:
_ = navigationController?.popViewController(animated: true)
let rootVC = navigationController?.topViewController as? RootViewVC
rootVC?.openLink(url: url)
return
Apple's swift guideline says: “You use a defer statement to execute a set of statements just before code execution leaves the current block of code. ”,but still I don't quite get it.
What's the difference between a defer statement and a statement right just before return?
All the difference in the world. The defer
statement is executed after the return! This allows you to accomplish things that can be accomplished in no other way.
For example, you can return a value and then change the value. Apple makes use of this trick quite regularly; here, for example, is code from the Sequence documentation showing how to write a custom Sequence:
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
If you wrote that as
count -= 1
return count
... it would break; we don't want to decrement count
and then return it, we want to return count
and then decrement it.
Also, as has been already pointed out, the defer
statement is executed no matter how you exit. And it works no matter you exit the current scope, which might not involve return
at all; defer
works for a function body, a while block, an if construct, a do block, and so on. A single return
is not the only way to exit such a scope! There might be more than one return
in your method, and/or you might throw an error, and/or you might have a break
, etc. etc., or you might just reach the last line of the scope naturally; the defer
is executed in every possible case. Writing the same code "by hand", so as to cover every possible exit, can be very error-prone.