Defer in Swift
Probably many posts have already been devoted to explain the use of defer
keyword in Swift. But my two cents here. Defer is the new keyword added to the Swift 2.0 to handle unseen developer bugs and simplify the program flow.
For more detailed and official explanation of
defer
, you can refer to Official Apple documentation on defer
Defer is usually used to cleanup the code after execution. This might involve deallocating container, releasing memory or close the file or network handle. When put into the routine, code inside defer
block is last to execute before routine exits. Routine in this case could refer to a function
. Sometimes when function returns there are hanging threads, incomplete operation which needs to cleanup. Instead of having them scattered across function, we can group them together and put in the defer block. When function exits, cleanup code in the defer
gets executed.
For e.g.
func doFileProcessing() {
defer {
// Close the file handle. Clear up unwanted resources. If networking API was used, close the network handle as well.
}
// Open file container, read file, store contents into collection. Update UI
}
In the above example, function doFileProcessing
will handle file operation. When function returns, instead of having to write file closing code anywhere in the routine, we have grouped it under defer
which gets executed at very end.
This is equally true if you prematurely return
from function before it reached an end. As soon as return
is called, the defer block gets executed before exiting the routine.
Now what happens when you have multiple defer
statements in the routine?
Personally I don't see any reason for having multiple
defer
statements as long as they are all responsible for cleanup operation. However, one might argue that you might haven
different resource open and to clear them up you can haven
defer blocks.
func doFileProcessing() {
defer {
// Close the file handle. Clear up unwanted resources. If networking API was used, close the network handle as well.
print("Third defer")
}
defer {
print("Second defer")
}
defer {
print("First defer")
}
// Open file container, read file, store contents into collection. Update UI
}
Can you guess in which order these defer
statements will get executed? As it is clear from original definition, defer
always follows reverse order. i.e. it is always the last statement to execute and it follows the order from bottom to top. Now given this explanation, the last defer
will always get executed first and following the bottom-up order, the first defer
will get executed at the last,
So above code will print following output,
First defer
Second defer
Third defer
Hope this blog post helps anyone who wants to utilize this modern construct in their app. Use it only for cleaning up resources. Please do not add any convoluted code or try to do an obscure sorcery with it.