본문 바로가기
⌨️ Language/swift

[Swift] Escaping Closure

by hyebin (Helia) 2023. 5. 20.

이스케이핑 클로저(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

댓글