Notice
Recent Posts
Recent Comments
Link
大器晩成
탈출 클로저(Escaping Closures) / 자동 클로저 (Autoclosures) 본문
[@escaping]
- 일반적으로 함수의 실행이 종료되면 파라미터로 쓰이는 클로저도 삭제됩니다.
- 함수에 인수로 전달하지만, 함수가 반환된 후 호출되는 클로저 함수를 탈출(escape)한다라고 말합니다.
- @escaping 키워드는 클로저를 제거하기 않고 함수에서 탈출시키도록 하며, 클로저가 함수의 실행 흐름을(스택프레임)을 벗어날 수 있도록 합니다.
non - escaping clousre
- 함수내부에서, 단순하게 실행하고 종료할 때 (클로저를 힙에 저장할 필요가 없습니다.)
func hello(clousre: (String) -> ()) {
let msg = "Hello Swift"
clousre(msg)
}
hello { msg in
print(msg)
}
- 일반적으로 함수의 실행이 종료되면 클로저는 삭제됩니다.
escaping clousre
- 함수의 실행을 벗어나도 사용이 필요한 경우 (힙에 저장되기 때문에, 메모리 관리가 필요함)
var squareFunction: (Int) -> () = {
print("\($0) * \($0) = \($0 * $0) 입니다. ")
}
squareFunction(10) // 10 * 10 = 100 입니다.
func square(closure: @escaping (Int) -> ()) {
squareFunction = closure // 클로저에 실행이 아닌, squareFunction 함수에 저장
}
square {
print("\($0)의 제곱은 = \($0 * $0) 입니다. ")
}
squareFunction(10) // 10의 제곱은 = 100 입니다.
- square함수를 호출할 때는 아무 일도 일어나지 않습니다.
- squareFunction 실제 외부 변수를 실행해야 동작합니다.
@escaping 사용의 대표적인 경우
- 어떤 함수의 내부에 존재하는 클로저(함수)를 외부 변수에 저장할 때
- GCD(비동키 코드를 사용할 때)
[@autoclosure]
- autoclousre는 함수에 인수로 전달되는 표현식을 래핑 하기 위해 자동으로 생성되는 클로저입니다. 인수를 가지지 않으며 호출될 때 내부에 래핑 된 표현식의 값을 반환합니다.
- 일반적으로 클로저 형태로 사용해도 되지만, 너무 번거로울 때 사용됩니다.
- 번거로움을 해결해 줄 수는 있지만, 실제 코드가 명확해 보이지 않아 사용을 지양하는 편입니다(애플 공식문서)
func even(closure: @autoclosure () -> Bool) {
if closure() {
print("짝수입니다.")
} else {
print("홀수입니다.")
}
}
//even(closure: Bool)
even(closure: 10 % 2 == 0)
autoclosure는 기본적으로 non-escaping 특성을 가지고 있습니다.
- autoclosure가 이스케이프를 허용하길 원한다면 @autoclousre와 @escaping 속성을 둘 다 사용하면 됩니다.
// Apple 공식문서 예제
var customersInLine = ["Barry", "Daniella"]
// customersInLine is ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
customerProviders.append(customerProvider)
}
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))
print("Collected \(customerProviders.count) closures.")
// Prints "Collected 2 closures."
for customerProvider in customerProviders {
print("Now serving \(customerProvider())!")
}
// Prints "Now serving Barry!"
// Prints "Now serving Daniella!"
print(customersInLine) // []
- 위의 코드에서 customerProvider 인수로 전달된 클로저를 호출하는 대신에 collectCustomerProviders(_:) 함수는 클로저를 customerProviders 배열에 추가합니다. 이 배열은 함수의 범위 밖에 선언됩니다. 이것은 배열에 클로저는 함수가 반환된 후에 실행될 수 있다는 의미입니다. 그 결과 customerProvider 인수의 값은 함수의 범위를 벗어날 수 있어야 합니다.
728x90
'iOS > Swift 문법' 카테고리의 다른 글
스위프트 메모리 관리 모델 ARC(Automatic Reference Counting) (0) | 2025.03.03 |
---|---|
고차함수 (0) | 2025.03.02 |
중첩함수 (클로저의 캡처와 동일한 현상) (0) | 2025.02.26 |
트레일링(Trailing)클로저 - 후행클로저 문법 (0) | 2025.02.25 |
클로저 (Closures) (0) | 2025.02.25 |