Using 'defer' in swift

September 5, 2023
1m 30s
programmingprogramming2swiftswift2featuredfeatured7

Swift remains at the forefront of iOS development with its focus on safety and clarity. Among its features, one stands out for its elegance and utility: the 'defer' keyword. This tool ensures that specific actions are taken as a scope concludes, regardless of how it terminates.

1. Basics of defer

The primary role of defer is to schedule code to be executed as the current scope is about to conclude. It doesn't matter if the scope completes naturally, due to a return statement, or even via an error.

func fetchData() -> Data? {
  let startTime = Date()
    
  defer {
      let duration = Date().timeIntervalSince(startTime)
      print("Data fetched in \(duration) seconds")
  }
  
  // Simulate data fetching
  return Data()
}

In the example, irrespective of how fetchData concludes, the time taken to fetch the data will be printed.

2. Error Management with defer

Especially beneficial when grappling with potential errors, defer ensures actions are undertaken even if an error cuts your function short:

func retrieveData() throws -> Data {
  let dataResource = try openDataResource()
  
  defer {
      closeDataResource(dataResource)
  }
  
  let contents = try dataResource.read()
  return contents
}

If dataResource.read() throws an error, our defer block will still ensure that the data resource is properly closed.

3. Multiple defer Statements

You can craft multiple defer blocks within one scope. They execute in the reverse of their order of definition:

func displayOrder() {
    defer { print("First defer block") }
    defer { print("Second defer block") }

    print("Main function body")
}

This yields:

Main function body
Second defer block
First defer block

4. Notable Considerations

While it's valuable, defer isn't meant to replace other constructs. For example, it's not an alternative to the finally block of other languages. It’s directly tied to its scope and activates accordingly.

func exampleUsingDefer() {
  print("Starting function")

  defer { 
    print("This will print just before the function exits") 
  }

  print("Function still in progress")
}

Executing the function will result in:

Starting function
Function still in progress
This will print just before the function exits

Conclusion

The defer keyword in Swift underscores the language's commitment to making coding not only efficient, but also intuitive. By ensuring specific actions occur at a scope's end, defer offers a potent tool for managing resources and simplifying error handling. As you craft more Swift code, consider how defer can make your routines clearer and safer.

All posts
John McGlone

Hi, I'm John McGlone, a Christian American husband, father, and software engineer. I believe that God's plan to make disciples of all nations will be successful.

Follow me on X, GitHub, and LinkedIn

John McGlone © 2023. All rights reserved.