ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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
Designed by Tistory.