A defer
statement consists of a block of code, which will be executed when a function returns and should be used for cleanup.
As Swift's guard
statements encourage a style of early return, many possible paths for a return may exist. A defer
statement provides cleanup code, which then does not need to be repeated every time.
It can also save time during debugging and profiling, as memory leaks and unused open resources due to forgotten cleanup can be avoided.
It can be used to deallocate a buffer at the end of a function:
func doSomething() {
let data = UnsafeMutablePointer<UInt8>(allocatingCapacity: 42)
// this pointer would not be released when the function returns
// so we add a defer-statement
defer {
data.deallocateCapacity(42)
}
// it will be executed when the function returns.
guard condition else {
return /* will execute defer-block */
}
} // The defer-block will also be executed on the end of the function.
It can also be used to close resources at the end of a function:
func write(data: UnsafePointer<UInt8>, dataLength: Int) throws {
var stream:NSOutputStream = getOutputStream()
defer {
stream.close()
}
let written = stream.write(data, maxLength: dataLength)
guard written >= 0 else {
throw stream.streamError! /* will execute defer-block */
}
} // the defer-block will also be executed on the end of the function