Swift:
Escaping vs Non-Escaping Closure
Swift에서 클로저를 함수의 인자로 사용할 때, 클로저가 함수의 스코프를 벗어나 실행되는지에 따라 escaping과 non-escaping으로 나뉘게 되는데, 자세히 알아보기 위해 작성!
Non-Escaping Closure
- 클로저가 함수의 실행 중에 호출되고 종료되는 경우
- 기본 클로저는
non-escaping
이라고 한다. - 함수 스코프를 벗어나지 않기 때문에
self
키워드를 명시하지 않아도 된다.1
2
3func executeImmediately(closure: () -> Void) {
closure()
}
Escaping Closure
- 클로저가 함수의 실행이 끝난 이후에도 나중에 호출될 가능성이 있는 경우
- 클로저 앞에
@escaping
키워드를 붙여야하며, 보통 비동기 작업, completion handler 등에 사용 된다. - self를 명시적으로 사용 (retain cycle 주의)
1
2
3
4
5var storedClosure: (() -> Void)?
func storeClosure(closure: @escaping () -> Void) {
storedClosure = closure
}
차이점
항목 | Non-Escaping Closure | Escaping Closure |
---|---|---|
실행 시점 | 함수 내부 즉시 실행 | 함수 외부에서 나중에 실행 |
self 사용 | 생략 가능 | 명시적 사용 필요 (self. ) |
메모리 관리 | 간단 | retain cycle 주의 필요 |
사용 예시 | 일반 함수 내부 로직 | 비동기 콜백, 네트워크 응답 등 |
키워드 필요 여부 | ❌ | ✅ (@escaping ) |
팁
URLSession
,DispatchQueue.main.async
등에 전달하는 클로저는 대부분escaping
- escaping 클로저를 캡처한 객체는 메모리 누수의 원인이 될 수 있으므로,
[weak self]
등을 고려한다!!!