@escaping
@escaping 은 클로저(closure)가 함수를 벗어나서 실행될 수 있음을 나타내는 특별한 프로퍼티입니다. 이것은 비동기 작업이나 클로저가 함수의 실행이 완료된 후에 호출되어야 하는 경우에 유용합니다.
기본적으로 Swift에서 함수의 클로저 매개변수는 함수 내에서만 실행되고 함수가 종료되면 클로저도 함께 종료됩니다. 하지만, escaping 클로저는 함수의 범위를 벗어나서(escape) 함수가 종료된 후에도 호출될 수 있습니다.
예를 들어, 비동기 작업을 수행하는 함수에서 escaping 클로저를 사용하는 경우의 예제 코드입니다.
func performAsyncTask(completion: @escaping () -> Void) {
DispatchQueue.global().async {
// 비동기 작업 수행
// ...
// 작업이 완료된 후 escaping 클로저 호출
completion()
}
}
// 함수 호출
performAsyncTask {
print("비동기 작업이 완료되었습니다.")
}
여기서 @escaping 키워드는 performAsyncTask 함수에 전달된 클로저가 함수 범위를 벗어나서 나중에 호출될 수 있다는 것을 나타냅니다. 이는 주로 비동기 작업을 수행할 때, 작업이 완료된 후에 특정 코드 블록을 실행하고자 할 때 사용됩니다.
Swift에서는 일반적으로 escaping 이 필요한 경우에만 @escaping 을 명시하며, 그렇지 않은 경우 기본적으로 escaping이 아닌 것으로 간주됩니다.
다른 예제로 API 를 사용하여 영화 정보를 가져오는 코드입니다. 웹 서비스와 통신을 하기 위해서는 결과를 비동기적으로 받아야하기에 @escaping 키워드를 사용하여 클로저 내에서 비동기적으로 실행되는 JSON 디코딩이 완료되면 completion 클로저가 호출되어 외부로 결과를 전달합니다. 이때 @escaping 이 사용되어 클로저가 함수 범위를 벗어나서 나중에 호출 될 수 있도록 합니다.
enum NetworkError: Error {
case badURL
case noData
case decodingError
}
class HTTPClient {
func getMoviesBy(search: String, completion: @escaping (Result<[Movie]?, NetworkError>) -> Void) {
guard let url = URL(string: "http://www.omdbapi.com/?s=\(search)&apikey=\(Constants.API_KEY)") else {
return completion(.failure(.badURL))
}
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
return completion(.failure(.noData))
}
guard let moviesResponse = try? JSONDecoder().decode(MovieResponse.self, from: data) else {
return completion(.failure(.decodingError))
}
completion(.success(moviesResponse.movies))
}
}
}
'SwiftUI' 카테고리의 다른 글
Modal View (sheet) (0) | 2023.12.19 |
---|---|
Custom Navigation Button (0) | 2023.12.18 |
MVVM Design Pattern (0) | 2023.12.15 |
Published (0) | 2023.12.15 |
Chart Proxy (0) | 2023.12.14 |