Escaping Closure이라고 어디선가 탈출한다는 의미이다. 그렇다면 어디서 탈출하는 것일까?
라는 생각을 해본다면, 함수 라이프사이클이라고 생각하면 난 편했다.
일반적으로 nonescaping 클로저에서는 함수 body에서 호출되고 있는 클로저는 항상 함수가 끝나기 전에 실행된다. 결국 함수 라이프사이클 내에서 실행된다고 볼 수 있다.
func performNonEscaping(closure: () -> ()) {
    print("start")
    closure()
    print("end")
}
performNonEscaping {
    print("closure")
}
이 코드에서 보자면, performNonEscaping()에서는 클로저를 파라미터로 받고있다. 이 클로저는 일반적으로 함수 내에서 만들어진 함수라고 볼 수 있다.(복사본) 그렇게 생각한다면, 함수가 끝나기 전까지 함수 내에 있는 모든 코드는 다 일어날 것이고 다 일어난뒤에는, 메모리가 다 반환되는 것이 정상이다.
하지만 함수 라이프사이클 내에서가 아닌 밖에서 클로저가 사용되어야하는 경우가 있을때, @escaping이라는 annotation을 클로저 앞에 붙인다.
탈출하는것은 함수 라이프사이클 밖에서도 closure가 실행되는 것을 의미한다. 함수의 정상적인 실행흐름을 탈출하는 것이다.
@escaping 클로저는 시작시점과 종료시점이 정확하지 않다. 결국 함수의 실행 흐름과 관련이 없어진다.
보통 비동기프로그래밍을 할때 함수의 실행흐름을 거스를때 사용한다.
func performEscaping(closure: @escaping () -> ()) {
    print("start")
    var a = 12
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        closure()
        for _ in 0...3 {
            a += 3
        }
        print(a)
    }
    print("end")
}
performEscaping {
    print("closure")
}
이 코드에서 본다면, escaping이 클로저 앞에 붙어있기 때문에 함수가 다 끝난 이후에도 그 클로저는 계속 실행될 예정이라는 것을 알 수 있다.
그러면 함수가 실행되면, 먼저 start가 프린트 되고, 비동기가 있기 때문에, 바로 end가 찍힌다. 이시점에서 performEscaping의 함수의. 라이프사이클은 끝이난다. 하지만 우리는 클로저를 escaping 시켰기 때문에, 이 클로저는 아직 살아있는 것이다.
3초가 지난뒤에 closure()가 발동되서 closure가 찍히고, 그리고 print(a)까지 완성된다. 
클로저의 실행이 완료될때까지 클로저를 제거하지 않는다. 그리고 클로저는 클로저 외부의 값을 캡쳐하고 있기 때문에, 그 값들도 계속 살아있다. 그래서 함수 밖에서 클로저의 기능과 클로저가 캡쳐한 값으로 무언가를 진행할 때 유용하다.
| [iOS] frame에 대한 간단한 이해 (0) | 2021.08.20 | 
|---|---|
| [IOS] DispatchGroup으로 여러 비동기 실행의 마지막을 잡는법 (0) | 2021.08.12 | 
| [Swift] capturing Closure (0) | 2021.08.02 | 
| [SWIFT] Protocol Comparable, Equatable (0) | 2021.07.17 | 
| [Swift] Enum 타입의 CaseIterable, CustomStringConvertible?? (0) | 2021.07.17 | 
댓글 영역