-
[Swift] @escaping 키워드와 클로저Swift 2023. 3. 11. 15:10
시작하며
javascript라는 법이 없는 나라에서 온 나는 Swift의 @escape 키워드가 당황스럽고 또 놀랍다. @escape는 클로저를 인자로 전달받는 함수 내부에서 외부로 클로저를 전달하는 경우(비동기 등으로 클로저를 전달 받았을 때) 사용하는 키워드이다. 어떤 경우에 사용하는지 알아보자.
escaping-closure and non-escaping-closure
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. When you declare a function that takes a closure as one of its parameters, you can write
@escaping before the parameter’s type to indicate that the closure is allowed to escape.escaping-closure는 인자로 전달받는 closure를 함수 외부에 할당하거나 함수가 종료된 이후에 사용하는 경우에 사용한다. 기본적으로 클로저는 non-escaping 클로저이기 때문에 다른 함수에 인자로 전달해주거나 클로적를 저장해 두고 사용하기 위해서는 closure를 받는 인자 앞에 @escaping 키워드를 붙여주어야 한다.
class Weather { var completion : (() -> Void)? func getWeather(completionHandler: @escaping () -> Void){ completion = completionHandler } }
escaping-closure와 weak self
closure는 context capture를 통해 클래스의 인스턴스를 참조한다. 따라서 @escaping 을 통한 클로저에 인자로 클로저를 보내는 경우 순환 참조(ARC)를 통한 메모리 누수가 발생할 가능성이 있다.
위와 같은 순환참조를 막기 위해 [weak self]를 통해 인스턴스에 대한 약한 참조를 함으로 순환참조를 대비할 수 있다. 예시를 통해 확인해보자.
final class WeatherManager { static let shared = WeatherManager() private init() {} typealias NetworkCompletion = (Result<WeatherData, NetworkError>) -> Void //⭐️ @escaping으로 다른 함수로 전달 가능한 escaping-closure로 변환 func getWeatherInfo(completion: @escaping NetworkCompletion){ let urlString = "\(WeatherAPI.requestURL)\(WeatherAPI.params)&appid=\(SecretKey.apiKey)" performRequest(urlString: urlString,completion: completion) } ... } ... func setupData(){ var weatherInfo: String? //⭐️ weak self ⭐️를 통한 약한 참조 weatherManager.getWeatherInfo { [weak self] result in switch result { case .success(let weatherData): self?.weatherInfo = weatherData.weather[0].main case .failure(let error): print(error.localizedDescription) } } }
getWeatherInfo라는 함수를 통해 클로저를 전달하는데 weak self 키워드를 통해 약한 참조를 통해 보내고 @escaping 키워드를 통해 받은 클로저를 다른 함수의 인자로 다시 보낼 수 있게 할 수 있었다.
References
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/
Documentation
docs.swift.org
https://velog.io/@parkgyurim/Swift-escaping-closure
[Swift] @escaping 클로저
📚 Swift @escaping 클로저에 대해 알아보자
velog.io
'Swift' 카테고리의 다른 글
[SwiftUI] @State와 @ObservableObject 알아보기 (0) 2023.03.21 [Network] URL로 네트워크 요청하기 (0) 2023.03.12 [Swift] 싱글톤(Singleton) 정리 (0) 2023.03.06 [Swift] Xcode .gitignore 파일 추가하기 (0) 2023.03.01 [Swift] 메모리 참조 strong, weak, unowned 비교 (0) 2023.02.09