클로저가 외부변수를 캡처하여 저장하고 나중에 사용하는 방법
func makeIncrementer(incrementAmount: Int) -> () -> Int {
var total = 0
let incrementer: () -> Int = {
total += incrementAmount // 외부변수 total을 참조(이 과정이 capture되는 상황)
return total
}
return incrementer
}
let incrementByTwo = makeIncrementer(incrementAmount: 2)
print(incrementByTwo()) // 2
print(incrementByTwo()) // 값을 보는 것이 아니라 주소를 참조하고 있기 때문에 변경된 값인 4가 출력된다.
함수의 전달인자로 전달한 클로저가 함수 종료 후에 호출될 때 클로저가 함수를 탈출한다고 표현한다.
typealias VoidVoidClosure = () -> Void
let firstClosure: VoidVoidClosure = {
print("Closure A")
}
let secondClosure: VoidVoidClosure = {
print("Closure B")
}
// first와 second 매개변수 클로저는 함수의 반환 값으로 사용될 수 있으므로 탈출 클로저이다.
func returnOneClosure(first: @escaping VoidVoidClosure, second: @escaping VoidVoidClosure, shouldReturnFirstClosure: Bool) -> VoidVoidClosure {
// 전달인자로 전달받은 클로저를 함수 외부로 다시 반환하기 때문에 함수를 탈출하는 클로저이다.
return shouldReturnFirstClosure ? first : second
}
// 함수에서 반환한 클로저가 함수 외부의 상수에 저장되었다.
let returnedClosure: VoidVoidClosure = returnOneClosure(first: firstClosure, second: secondClosure, shouldReturnFirstClosure: true)
returnedClosure() // "Closure A" 출력
var closures: [VoidVoidClosure] = []
// closure 매개변수 클로저는 함수 외부의 변수에 저장될 수 있으므로 탈출 클로저이다.
func appendClosure(closure: @escaping VoidVoidClosure) {
// 전달인자로 전달받은 클로저가 함수 외부의 변수 내부에 저장되므로 함수를 탈출한다.
closures.append(closure)
}