-
escaping closure(탈출 클로저)Swift 2021. 12. 23. 14:58
안녕하세요.
오늘은 escaping closure에 대해서 알아보도록 하겠습니다.
그러기 위해선 먼저 closure에 대해서 알아야겠죠?
closure는 특정 기능들을 하는 코드를 하나의 블럭이라고 보시면 될 것 같습니다.
저희는 이미 그런 기능을 하는 친구를 알고 있죠?
바로 함수입니다.
사실 함수도 closure의 일종입니다.
Swift에서 closure는 1급 객체인데요.
이게 무슨 소리냐
다른 변수에 할당할 수 있고, 인자로 사용될 수 있고, 반환값으로 사용될 수 있다는 것을 의미합니다.
// 변수에 할당 let plus: (Int, Int) -> Int = { a, b in return a + b } // 매개변수로 사용 func calculateTwoAndThree(formula: (Int, Int) -> Int) -> Int { formula(2, 3) } calculateTwoAndThree(formula: plus) // 반환값으로 사용 func number() -> (Int) -> Void { return { print($0) } } let printTask = number() printTask(3)
이런 느낌들로 사용될 수 있다는 의미입니다.
그렇다면 escaping closure는 무엇이냐?
함수의 인자로 사용된 클로저가 함수가 반환된 후에 호출될 때 클로저가 함수를 탈출했다고 말합니다.
@escaping 키워드를 사용하면 클로저를 탈출 클로저로 사용할 수 있습니다.
탈출 클로저를 사용하면 인자로 사용된 클로저를 외부에 저장하거나 반환값으로 사용할 수 있습니다.
그러나 저는 탈출 클로저를 주로 비동기 작업을 할 때 사용합니다.
이런 식으로 함수가 종료된 이후에도 completion이 실행되는 것을 볼 수 있어요.
URLSession의 DataTask를 예로 들어보겠습니다.
URL로부터 콘텐츠를 받아올 때 사용하는 메소드인데요.
아래와 같이 completionHandler라는 메소드가 @escaping 키워드를 사용하고 있는 것을 확인할 수 있습니다.
URL로부터 응답이 올 때까지 함수 안에서 기다릴 수는 없자나요?
그래서 탈출 클로저를 사용해서 함수는 바로 종료시키되 URL로부터 응답이 오면 completionHandler가 실행되도록 한 것입니다.
또한 UI 작업을 해야하는 클로저가 인자로 사용될 경우 해당 클로저는 main queue에서 실행이 되야 하기 때문에 탈출 클로저여야 합니다.
+ Optional 타입의 클로저는 왜 escaping이 기본일까?
위에서 예시로 설명한 dataTask와 달리
UIViewController의 dismiss 메소드는 completion 클로저를 매개변수로 받음에도 불구하고 @escaping 키워드를 사용하고 있지 않습니다.
옵셔널 타입의 클로저 매개변수에 @escaping 키워드를 채택하면
이미 escaping하다는 에러를 보여주는데요.
그 이유는 옵셔널 타입의 클로저 매개변수는 클로저 타입이 아니기 때문입니다.
옵셔널 타입의 클로저 매개 변수는 제네릭 타입입니다.
@escaping 키워드의 경우 클로저타입에만 붙일 수 있는데
제네릭 타입에 붙이려 하니 이런 에러를 보이는 것입니다.
오늘은 여기까지 하겠습니다.
혹시라도 잘못된 정보나 알려주실 정보가 있으면 알려주시면 감사하겠습니다.
'Swift' 카테고리의 다른 글
Codable (0) 2021.12.28 NSCoder (0) 2021.12.27 Hashable (0) 2021.12.17 String은 왜 Int로 Subscript 되지 않을까? (0) 2021.12.15 class 와 struct 그리고 enum (4) 2021.12.14