Swift Defer Statement

Execute cleanup code when leaving scope

โฐ What is Defer Statement?

Swift defer statements execute code just before leaving the current scope. They ensure cleanup tasks run regardless of how the function exits, making resource management safer and more reliable.


// Basic defer example
func processFile() {
    print("Opening file...")
    defer {
        print("Closing file...")
    }
    print("Processing file...")
}
processFile()
                                    

Output:

Opening file...

Processing file...

Closing file...

Defer Statement Features

๐Ÿงน

Cleanup Guarantee

Always executes before scope exit

defer {
    cleanup() // Always runs
}
๐Ÿ“š

LIFO Order

Last defer executes first

defer { print("First") }
defer { print("Second") }
// Prints: Second, First
๐Ÿ”’

Resource Safety

Perfect for file/memory management

let file = openFile()
defer { file.close() }
๐ŸŽฏ

Any Exit Path

Runs on return, throw, or natural exit

defer { cleanup() }
if error { return } // Still runs

๐Ÿ”น Defer Execution Order

Multiple defer statements execute in reverse order (LIFO):

func demonstrateOrder() {
    print("Function starts")
    
    defer {
        print("Defer 1: This runs third")
    }
    
    print("Middle of function")
    
    defer {
        print("Defer 2: This runs second")
    }
    
    defer {
        print("Defer 3: This runs first")
    }
    
    print("Function about to end")
}

demonstrateOrder()

Output:

Function starts

Middle of function

Function about to end

Defer 3: This runs first

Defer 2: This runs second

Defer 1: This runs third

๐Ÿ”น Resource Management Example

Perfect for ensuring resources are properly cleaned up:

func processDatabase() {
    print("Connecting to database...")
    defer {
        print("Disconnecting from database...")
    }
    
    print("Starting transaction...")
    defer {
        print("Committing transaction...")
    }
    
    // Simulate some work
    let success = true
    
    if !success {
        print("Error occurred!")
        return // defer blocks still execute
    }
    
    print("Processing data...")
    print("Work completed successfully")
}

processDatabase()

// File handling example
func readConfigFile() -> String? {
    print("Opening config file...")
    defer {
        print("Closing config file...")
    }
    
    // Simulate file operations
    let fileExists = true
    guard fileExists else {
        print("File not found!")
        return nil // defer still runs
    }
    
    print("Reading file contents...")
    return "config data"
}

let config = readConfigFile()

Output:

Connecting to database...

Starting transaction...

Processing data...

Work completed successfully

Committing transaction...

Disconnecting from database...

Opening config file...

Reading file contents...

Closing config file...

๐Ÿ”น Defer with Error Handling

Defer ensures cleanup even when errors are thrown:

enum FileError: Error {
    case notFound
    case corrupted
}

func processFileWithErrors() throws {
    print("Starting file processing...")
    defer {
        print("Cleanup: Releasing resources...")
    }
    
    defer {
        print("Cleanup: Clearing temporary data...")
    }
    
    // Simulate file operations
    let fileExists = false
    guard fileExists else {
        print("File not found!")
        throw FileError.notFound // defer blocks still execute
    }
    
    print("File processed successfully")
}

// Test error handling
do {
    try processFileWithErrors()
} catch {
    print("Caught error: \(error)")
}

// Defer in loops
func processItems() {
    let items = ["item1", "item2", "item3"]
    
    for item in items {
        print("Processing \(item)...")
        defer {
            print("Finished processing \(item)")
        }
        
        // Simulate work
        if item == "item2" {
            print("Skipping \(item)")
            continue // defer still runs for this iteration
        }
        
        print("Successfully processed \(item)")
    }
}

Output:

Starting file processing...

File not found!

Cleanup: Clearing temporary data...

Cleanup: Releasing resources...

Caught error: notFound

๐Ÿง  Test Your Knowledge

In what order do multiple defer statements execute?