[Swift] Closures(2)

상 원·2022년 7월 8일
0

Swift

목록 보기
12/31
post-thumbnail

Escaping Closures

함수의 인자로 전달됐다가 함수의 리턴 이후 실행되는 클로저를 escape했다고 말한다.
그래서 함수 매개변수에 클로저가 들어갈 때, 얘가 escape 할 수 있다는 것을 의미하기 위해 매개변수 타입 앞에다가 @escape annotation을 쓸 수 있다.

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

여기서 @escaping을 통해 escaping closure라는 것을 알 수 있음.
someFunctionWithEscapingClosure 함수는 completionHandler 클로저를 실행시키지 않고 반환되고, 이 클로저는 아직 실행되지 않은 상태이다.
이때 compeltionHandlers 배열에 이 클로저를 집어넣는 거임.

func someFunctionWithNonescapingClosure(closure: () -> Void) {
    closure()
}

class SomeClass {
    var x = 10
    func doSomething() {
        someFunctionWithEscapingClosure { self.x = 100 }
        someFunctionWithNonescapingClosure { x = 200 }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)
// Prints "200"

completionHandlers.first?()
print(instance.x)
// Prints "100"

self 도 명시를 해 줘야 한다. non-escaping 클로저는 암시적으로 그냥 사용하면 됐지만, escaping 클로저는 self를 써 줘야 함.
공식문서에 있는 예제는 해석하기 좀 어려워서 다음에 보고,
이 escaping closure가 쓰이는 이유를 알아보자.

Escaping closure는 A 함수가 마무리된 상태에서만 B 함수를 실행시킬 수 있다는 장점이 생김!
즉, 비동기 처리를 할 때 편리해지는데, 대표적인 사용처가 HTTP Request CompletionHandler라고 한다.
HTTP Request 를 할 때는 내가 Request를 서버에 전송하고, 서버에서 주는 Response를 받아야 하는데, 이 Response를 받아오는 함수들이 비동기로 작동해서 Request를 주자마자 반환되버림.

이 Response가 Request 결과를 기다리게 하려면? 바로 Escaping closure를 쓰는 것!!

Escaping Closure를 사용하면 함수의 실행 순서를 정할 수 있다!

profile
ios developer

0개의 댓글