안녕하세요.
대충은 알지만 대충 알고 있던 @propertywrapper에 대해서 알아볼게요.
# @propertywrapper란?
propertywrapper는 프로퍼티가 저장되는 방식을 관리하는 코드와 프로퍼티를 정의하는 코드를 분리하는 역할을 합니다.
예를 들어, 프로퍼티에 값을 저장하기 전에 thread-safety 검사를 해야 하는 상황이 있다고 가정해 볼게요. 이 경우, 모든 프로퍼티에 대해 thread-safety 검사를 하는 코드를 작성해야 합니다.
하지만, propertywrapper를 사용하면 관리 코드를 포함한 propertywrapper를 정의해 두고, 여러 프로퍼티에 해당 propertywrapper를 적용하여 관리 코드를 재사용할 수 있어요.
# propertywrapper 정의 및 사용법
propertywrapper를 정의하려면, wrappedvalue 프로퍼티를 정의한 구조체, enum, 클래스를 만들어야 해요.
아래 코드에서 TwelveOrLess 구조체는 wrappedvalue가 항상 12 이하의 숫자를 갖도록 합니다.
[주의] wrapperValue를 제외한 대부분의 property는 private으로 선언할 것!
propertywrapper 내부에서만 접근할 수 있도록 보장하기 위함이에요.
propertywrapper를 사용하려면 프로퍼티 앞에 propertywrapper를 attribute(속성)으로 작성합니다.
[참고] propertywrapper는 local stored 변수에 적용할 수 있고, 전역 변수랑 computed 변수에는 사용할 수 없습니다.
# propertywrapper의 초기값 설정
init 생성자를 추가해서 propertywrapper의 초기값을 설정할 수 있어요.
아래처럼 그냥 propertywrapper 속성만 적용된 프로퍼티는 init() 생성자가 호출됩니다.
아래처럼 초기값을 넣어준다면 init(wrappedValue:) 생성자가 호출됩니다.
이렇게 하면 init(wrappedValue:maximum:) 생성자가 호출되구요.
요렇게도 쓸 수 있습니다. height는 init(wrappedValue:) 생성자가 호출되고 width는 init(wrappedValue:maximum:) 생성자가 호출되겠죠?
# projectedValue
propertywrapper는 래핑 된 값 외에도 projectedValue라는 것을 추가로 정의할 수 있어요.
projectedValue의 이름은 wrappedValue와 동일하지만 앞에 $를 붙여줘야 하고, 어떤 타입의 값이든 반환할 수 있습니다.
(다른 인스턴스를 반환하거나 self를 반환할 수도 있습니다.)
아래는 projectedValue가 정의된 propertywrapper 예시입니다.
projectedValue는 언제 쓰면 좋을지 고민해 봐야겠어요ㅠ
# 활용
UserDefaults에 접근하는 propertywrapper를 정의하는 것이 대표적인 활용 방법입니다.
아래를 참고해 주세요!
# 참고
이번 글은 여기서 마무리.
'Swift' 카테고리의 다른 글
map, compactMap, flatMap (0) | 2024.08.18 |
---|---|
lazy var 클로저에서 retain cycle이 생기는 경우 (0) | 2024.06.20 |
protocol initializer가 클래스에서 required로 정의되어야 하는 이유 (0) | 2024.05.12 |
propertyWrapper로 UserDefaults 관리 (0) | 2024.05.11 |
@discardableResult (0) | 2024.01.28 |