iOS/Swift

클로저 5편

밤새는 탐험가89 2024. 2. 13. 23:53

 

 

 @autoclosure

 

파라미터로 전달된 일반 구문 & 함수를 클로저로 래핑(Wrapping)하는 것을 말함 

 

 

"@autoclosure" 라는 키워드를 파라미터 함수 타입 앞에 사용

func runFunction(closure: @autoclosure ()->()) {
    // 내부코드 
}

 

 

여기서 closure 라는 파라미터는 

실제로 클로저를 받지 않았지만, 클로저처럼 사용 가능

 

※ 단, 실제 클로저를 전달받지 않았기 때문에 

파라미터로 값을 넘기는 것 처럼 ( ) 를 통해 구문을 넘기는게 가능 

 

runFunction(closure: 22>=23)

 

" 22>=23" 은 일반 구문이지만, 실제로는

@autoclosure로 설정했기 때문에 클로저처럼 사용 가능 

 

 

@autoclosure는 클로저가 호출되기 전까지 클로저 내부의 코드가 동작하지 않음

즉, 지연 연산이 가능함 

이를 통해 연산에 자원을 많이 소모되는 부작용이 우려될 때 유용하게 사용 가능 

 

 

아래 코드를 통해 클로저가 연산을 어떻게 지연시키는지 알 수 있음 

 

var customersInLine: [String] = ["jerry", "mike", "tom", "marry"]
print(customersInLine.count)    // 4


// 클로저를 이용, 클로저 내부의 코드를 미리 실행하지 않고, 가지고만 있음
let customerProvider: () -> String = {
    return customersInLine.removeFirst()
}
print(customersInLine.count)    // 4

 

 

customerProvider 상수에 저장해둔 클로저는 

바로 아래 customerInLine.count 구문을 실행해도 

클로저 내부의 연산은 방영되지 않음

 

 

// 실제로 실행

print("Now serving \(customerProvider())!")    // Now serving jerry!
print(customersInLine.count)  // 3

 

 

customerProvider 라는 클로저를 실행해야 연산 진행

 

따라서 클로저를 실행하지 않는다면? 연산은 진행되지 않음

 

 

 

같은 조건의 클로저를 함수의 전달인자로 전달한다면?

var customersInLine: [String] = ["jerry", "mike", "tom", "marry"]
print(customersInLine.count)    // 4


func serveCustomer(_ customerProvider:() -> String) {
    print("Now serving \(customerProvider())!")
}

serveCustomer( { customersInLine.removeFirst() }) // Now serving jerry!

 

 

 

위의 코드를 다시 자동 클로저를 사용한다면?

var customersInLine: [String] = ["jerry", "mike", "tom", "marry"]
print(customersInLine.count)    // 4


func serveCustomer(_ customerProvider: @autoclosure () -> String) {
    print("Now serving \(customerProvider())!")
}

serveCustomer(customersInLine.removeFirst()) // Now serving jerry!

 

 

 

@autoclosure 라는 속성을 부여한 매개변수는 클로저 대신에

serveCustomer( { customersInLine.removeFirst() })

 

 

customersInLine.removeFirst() 코드의 실행 결과인 String 타입의 문자열

전달인자로 받게 됨 

 

serveCustomer(customersInLine.removeFirst())

 

 

여기서 String 타입의 값을 전달 받는 이유는

자동 클로저의 반환 타입이 ( ) -> String 이기 때문

 

 

자동 클로저는 전달인자를 갖고 있지 않기 때문에 

반환 타입의 값이 자동 클로저의 매개변수로 전달되면

이를 클로저로 자동으로 변환해줌 

 

'iOS > Swift' 카테고리의 다른 글

확장 (Extension)  (0) 2024.05.24
클로저 6편  (1) 2024.02.17
클로저 4편  (0) 2024.02.10
클로저 3편  (0) 2024.02.10
클로저 2편  (2) 2024.02.08