정의
- Escaping Closure는 클로저가 함수의 인자로 전달될 때, 함수가 반환(함수가 종료)된 후 실행되는 것을 의미합니다.
- Escaping Closure를 활용해 함수 사이에 실행 순서를 지정할 수 있습니다.
- completion 타입에 @escaping를 사용해 Escaping Closure라는 것을 명시합니다.
- 반대로 함수의 실행이 종료되기 전에 클로가 실행되는 Non-Escaping Closure도 있습니다.
예제 1 : Non-Escaping Closure
- 다음 클로저의 실행 순서를 통해 어떤 클로저인지 알아보겠습니다.
func runClosure(closure: () -> Void) {
closure()
}
- 먼저 runClosure( )함수의 인자로 closure가 전달됩니다.
- runClosure( ) 함수 안에서closure( )가 실행됩니다.
- runClosure( ) 함수가 값을 반환하고 종료됩니다.
- 실행 순서를 통해 closure는 함수가 종료되기 전에 실행되는 Non-Escaping클로저라는 것을 알 수 있습니다.
예제 2 : Escaping Closure
- 다음 클로저의 순서부터 알아보겠습니다.
- 클로저가 fetchData( ) 함수의 completion 인자로 전달됩니다.
- 클로저 completion이 completionhandler변수에 저장됩니다.
- fetchData( ) 함수가 값을 반환하고 종료됩니다.
- 함수가 종료됐지만, 클로저 completion은 아직 실행되지 않았습니다.
class ViewModel {
var completionhandler: (() -> Void)? = nil
func fetchData(completion: @escaping () -> Void) {
completionhandler = completion
}
}
- completion은 함수의 실행이 종료되기까지 실행되지 않은 것을 보아 함수 밖에서 실행되는 Escaping Closure임을 알 수 있습니다.
@escaping 사용
- 함수 작성 시에 @escaping를 사용한다고, 반드시 Escaping Closure가 사용되지 않습니다.
- 다음과 같이 @escaping를 사용해도, Non-Escaping Closure로 사용할 수 있습니다.
func runClosure(closure: @escaping () -> Void) {
closure()
}
- 반대로 Escaping Closure를 @escaping 없이 사용하면 어떻게 될까요?
- 이때는 @escaping가 누락되어 컴파일 에러가 발생하게 됩니다. 즉, 반대의 경우로는 사용할 수 없습니다.
class ViewModel {
var completionhandler: (() -> Void)? = nil
func fetchData(completion: () -> Void) {
completionhandler = completion
}
}
Non-Escaping Closure와 Escaping Closure
- 그렇다면 왜 굳이 Non-Escaping Closure와 Escaping Closure를 구분해서 사용할까요?
- Non-Escaping Closure를 사용함으로 상황에 따라 클로저에서 사용하는 특정 객체에 대한 retain, release, 등,, 의 처리를 생략해 객체의 Life-Cycle(생명주기)을 효율적으로 관리할 수 있습니다.
- 반대로 생각하면, Escaping Closure에서는 클로저가 함수 밖에서 실행되기 때문에 클로저에서 사용하는 객체에 대한 추가적인 Reference-Cycle(참조 주기)을 관리해줘야 합니다.
- 그렇기 때문에 두 가지 방식에 대한 구분을 둔 것이며,
적절한 상황에 알맞은 Closure방식을 사용함으로 컴파일러의 퍼포먼스와 최적화에 영향을 미칠 수 있습니다.
내용 출처
https://jusung.github.io/Escaping-Closure/
'iOS > iOS' 카테고리의 다른 글
Class와 Struct의 차이 (0) | 2022.02.25 |
---|---|
as, as?, as!의 차이 (0) | 2022.02.24 |
ARC [ Automatic Reference Counting ] (0) | 2022.02.22 |
SceneDelegate란? (0) | 2022.02.21 |
ViewController 생명주기 (0) | 2022.02.19 |
댓글