클로저란?
- 클로저(Closure)는 코드 블록으로, 변수처럼 전달되거나 저장될 수 있는 일급 객체입니다.
- Swift에서 함수의 인자로 자주 사용되며, 비동기 작업이나 콜백 처리에 널리 활용됩니다.
non-escaping 클로저
- 기본값: Swift의 함수 파라미터로 전달되는 클로저는 기본적으로 non-escaping입니다.
- 함수의 실행이 끝나기 전에 클로저가 반드시 실행됩니다.
- 클로저 내부에서
self를 명시하지 않아도 됨
func doSomething(closure: () -> Void) {
closure()
}
특징
- 클로저가 스택에 저장됨 → 빠르고 효율적
- 메모리 관리가 간단함
@escaping 클로저
- 함수가 끝난 이후에도 실행될 수 있는 클로저에 사용
- 예: 비동기 작업 (네트워크 요청, Completion Handler 등)
- 클로저가 함수 외부로 탈출(escape) 하기 때문에
@escaping 키워드 필요
- 클로저 내부에서
self를 사용할 때 명시적 캡처 필요 ([weak self], self. 등)
func fetchData(completion: @escaping () -> Void) {
DispatchQueue.global().async {
completion()
}
}
특징
- 클로저가 Heap에 저장됨 → 참조 관리 필요
- retain cycle 주의 필요
차이 요약
| 항목 | non-escaping | @escaping |
|---|
| 실행 시점 | 함수 내에서 즉시 실행 | 함수 종료 후에도 실행 가능 |
| 메모리 | Stack에 저장 | Heap에 저장 |
self 사용 | 생략 가능 | 명시적 사용 필요 |
| 예시 | 일반적인 내부 처리 | 비동기 처리, completion handler |
주의사항
- @escaping 클로저는 캡처한 객체와의 retain cycle 방지에 주의해야 함
- 클로저 내에서
[weak self], [unowned self] 사용 권장
결론
- 비동기 작업, 콜백 등 함수 외부에서 실행될 가능성이 있다면
@escaping 필수
- 기본은 non-escaping이므로 꼭 필요한 경우에만 escaping 사용