티스토리 뷰

IOS

[Swift] AutoClosure 에 대해서...

sulkun 2022. 4. 26. 18:01
반응형

 @autoclosure 란 말그대로 함수로 전달되는 인자(argument)를 코드를 감싸서 자동으로 클로저로 만들어주는 역할을 합니다.

(An autoclosure is a closure that’s automatically created to wrap an expression that’s being passed as an argument to a function)

 

@autoclosure 는 argument 를 가지지 않으며 리턴값이 있어야합니다. 

 

@autoclosure 는 기본적으로 non-escaping 클로저 입니다. 만약 사용 하고 싶다면 @autoclosure @escaping 입력해줘야됩니다.

물론 escaping 하게 되면 실행이 끝날때까지 기다리게 됩니다.(delay) 성능과 연관 됨으로 잘사용해야 합니다.

 

=> syntactic convenience 는 함수 parameter에 중괄호를 쓰는 것을 생략할 수 있게 해줍니다.

 


 # make use of autoclosure 를 animation에 사용하면..

하위 예제는 https://jusung.github.io/AutoClosure/ 가져왔습니다.

1. UIView.animate 

- before

UIView.animate(withDuration: 0.5) {
   self.view.frame.origin.x = 200
}

- after

func animate(_ animation: @autoclosure @escaping () -> Void, duration: TimeInterval = 0.5) {
   UIView.animate(withDuration: duration, animations: animation)
}

// 이 함수를 사용하면 {...} 구문 없이 같은 에니메이션 코드를 수행할 수 있습니다.
animate(self.view.frame.origin.x = 200)

# make use of autoclosure 를 Dictionary에 사용하면..

 

* Apple의 갯수를 얻고자 한다면 dictionary에서 특정 key에 대한 값이 없을 수 있기 때문에 Optional로 반환됩니다.

   옵셔널인 Int? 대신 Int로 값을 저장하고 싶다면 ??을 사용해  옵셔널일때의 값을 지정해야 합니다.

/**
* Apple의 갯수를 얻고자 한다면 dictionary에서 특정 key에 대한 값이 없을 수 있기 때문에 
* Optional로 반환됩니다. 옵셔널인 Int? 대신 Int로 값을 저장하고 싶다면 ??을 사용해 
* 옵셔널일때의 값을 지정해야 합니다.
*/
let fruits = ["Apple": 20, "Banana": 30, "Orange": 40]

let apple = (fruits["Apple"]) ?? 0

 

위의 코드 왼지 장황해 보입니다. 이때 @autoclosure를 사용하면 개선 할수 있습니다.

 

// [Int] 버전
extension Dictionary where Value == Int {
    func value(forKey key: Key, defaultValue: @autoclosure () -> Int) -> Int {
        guard let value = self[key] else { return defaultValue() }

        return value
    }
}


// [Generic] 버전
extension Dictionary {
    func value<T>(forKey key: Key, defaultValue: @autoclosure () -> T) -> T {
        guard let value = self[key] as? T else { return defaultValue() }

        return value
    }
}

// 이 익스텐션을 사용하면 위의 Dictionary에서 특정 키값에 접근하고, 
// 키값이 없을시 기본 값을 갖는 코드를 다음과 같이 표현할 수 있습니다.
let apple = fruits.value(forKey: "Apple", defaultValue: 0)

# conclusion

extention으로 범용 적으로 활용하여 리펙토링을 했을때 코드가 간결해 지는것을 확인해였습니다.

단 너무 난발 하거나 잘못 된 사용은 가독을 떨어질 수 있고, 코드가 어려워 보일 수 도 있다고 생각합니다.

 

많은 예제를 통해서 autoclosure의 활용해 보면서 학습한다면,
가독성과 성능 두마리를 잡을 수 있다고 생각합니다.
하위 링크에 예시가 많습니다. 확인하고 내일은 좀 더 다르게 코드 해요
https://medium.com/ios-os-x-development/https-medium-com-pavelgnatyuk-autoclosure-what-why-and-when-swift-641dba585ece

 

 

 

위의 내용은 토미님의 내용을 본문 내용을 인용했습니다. 

 

 

반응형
댓글