이스케이핑 클로저(Escaping Closure)
- escaping 클로저는 클로저가 함수의 인자로 전달됐을 때, 함수의 실행이 종료된 후 실행되는 클로저
- 파라미터 타입 앞에 @escaping 이라는 키워드를 명시해야 함
- 이스케이핑 클로저에서는 self를 명시적으로 언급해야 함
- 이스케이핑 클로저가 사용되는 예로는 비동기로 실행되는 HTTP Request CompletionHandler이 있음
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
Non-Escaping Closure
- 함수 내부에서 직접 실행하기 위해서만 사용
- 파라미터로 받은 클로저를 변수나 상수에 대입할 수 없음
- Non-escaping 클로저가 변수나 상수에 할당되면 클로저가 원래 범위 밖에서 저장 및 실행될 수 있으므로 예상하지 못한 동작 및 메모리 누수 발생 가능
func outer(closure: () -> ()) {
var i = closure // @escaping으로 타입 추로됨, 오류가 발생하지 않음
var j: () -> () = closure // 타입 명시, 오류 발생
}
- 중첩 함수에서 클로저를 사용할 경우, 중첩함수를 리턴할 수 없음
func outer(closure: () -> ()) -> () -> () {
func inner() {
closure()
}
return inner
}
print(outer {
print("1")
})
func outer() -> (){
private func ii() {
print(1)
}
return ii()
}
print(outer())
- 함수의 실행 흐름을 탈출하지 않아, 함수가 종료되기 전 무조건 실행되어야 함
Non-Escaping Closure 와 Escaping Closure
- 컴파일러의 퍼포먼스와 최적화 때문에 escaping, non-escaping 클로저를 나눠서 사용
- non-escaping 클로저는 컴파일러가 클로저의 실행이 언제 종료되는지 알기 때문에, 때에 따라 클로저에서 사용하는 특정 객체에 대한 retain, release 등의 처리를 생략해 객체의 라이프싸이클(life-cycle)을 효율적으로 관리 가능
- esacping 클로저는 함수 밖에서 실행되기 때문에 클로저가 함수 밖에서도 적절히 실행되는 것을 보장하기 위해, 클로저에서 사용하는 객체에 대한 추가적인 참조싸이클(reference cycles) 관리 등을 해줘야 함
- 컴파일러의 퍼포먼스와 최적화에 영향을 끼치기 때문에 Swift에서는 필요할 때만 escaping 클로저를 사용하도록 구분
반응형
'⌨️ Language > swift' 카테고리의 다른 글
[Swift] 변수와 프로퍼티2 (1) | 2024.03.15 |
---|---|
[Swift] 변수와 프로퍼티1 (0) | 2024.03.15 |
[Swift] 접근 제어 (Access Control) (0) | 2023.02.07 |
[Swift] ARC (0) | 2023.02.07 |
[Swift] 제네릭 (Generic) (0) | 2023.02.07 |
댓글