Câu hỏi phỏng vấn Swift
Câu hỏi

What is the difference between @escapi...

Câu trả lời

In Swift, closures are self-contained blocks of code that can be passed around and used in your code. They can be classified into two types: escaping and non-escaping closures. Understanding the difference between these two types is crucial for effective Swift programming, especially when dealing with asynchronous operations and memory management.

Non-Escaping Closures

By default, closures in Swift are non-escaping. A non-escaping closure is a closure that is called within the function it was passed to, before the function returns. This means that the closure does not outlive the function it was passed into. Once the function completes its execution, the closure is deallocated from memory. Non-escaping closures are simpler and more efficient because the compiler can optimize their memory usage and they do not require explicit handling of self to avoid retain cycles.

Example:

func performOperation(operation: () -> Void) {
    // Execute operation closure
    operation()
}

performOperation {
    print("Operation is complete")
}

In this example, the operation closure is executed immediately within the performOperation function, and it does not outlive the function's scope[1][2][6].

Escaping Closures

An escaping closure, on the other hand, is a closure that is called after the function it was passed to returns. This means that the closure can outlive the function it was passed into. To indicate that a closure is escaping, you must mark it with the @escaping keyword in the function definition. Escaping closures are commonly used in asynchronous operations, such as network requests, where the closure needs to be called after the operation completes.

Example:

func loadData(completion: @escaping (_ data: Data?) -> Void) {
    DispatchQueue.global().async {
        let data = try? Data(contentsOf: URL(string: "https://example.com")!)
        DispatchQueue.main.async {
            completion(data)
        }
    }
}

loadData { data in
    guard let data = data else {
        print("Failed to load data")
        return
    }
    print("Data loaded: \(data)")
}

In this example, the completion closure is marked as @escaping because it is called asynchronously after the loadData function has returned[2][3][4].

Key Differences

  1. Lifetime:

    • Non-Escaping: The closure is executed within the function's scope and deallocated once the function returns.
    • Escaping: The closure can be executed after the function returns, meaning it can outlive the function's scope.
  2. Memory Management:

    • Non-Escaping: The compiler ...
expert

expert

Gợi ý câu hỏi phỏng vấn

senior

What’s the difference between a static variable and a class variable?

expert

What is the Never return type? When to use it over Void ?

middle

Explain the defer usage in Swift

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào