Swift 5.1에서 추가된 기능으로, 해석 그대로 프로퍼티를 한번 감싸는 것을 의미한다.
Property Wrapper를 사용하면 프로퍼티가 저장되는 방식을 관리하는 코드와 프로퍼티를 정의하는 코드 사이에 분리 계층을 추가하여 프로퍼티를 관리할 수 있다.
만약 특정 문자열 프로퍼티의 값을 대문자로만 사용하고 싶을 때, Property Wrapper를 사용하지 않고
연산 프로퍼티로 구현하면 아래와 같이 코드를 작성할 수 있다.
@propertyWrapper
struct Uppercase {
private var value: String
// wrappedValue는 필수 구현사항
var wrappedValue: String {
get { return self.value.uppercased() }
set { self.value = newValue }
}
init(wrappedValue initialValue: String) {
self.value = initialValue
}
}
위 코드를 Property Wrapper를 사용하여 적용하면 프로퍼티 자체에 연결할 수 있어서
보일러플레이트 코드와 코드 재사용성을 높혀준다.
프로퍼티를 가질 수 있는 타입(class, struct, enum)에 @Property Wrapper 키워드를 붙여서 구현하며, 프로퍼티가 해야할 행동을 정의하는 타입으로 사용할 수 있게 한다.
여기서 @Property Wrapper 키워드는 직접 사용하려는 타입에 붙이는게 아니라 (위 코드에서는 Person타입)
프로퍼티가 해야 할 행동을 정의하는 타입에 붙여준다.
@propertyWrapper
struct Uppercase {
private var value: String
// wrappedValue는 필수 구현사항
var wrappedValue: String {
get { return self.value.uppercased() }
set { self.value = newValue }
}
init(wrappedValue initialValue: String) {
self.value = initialValue
}
}
struct Person {
@Uppercase
var name: String
}
var somePerson = Person(name: "abcd")
print(somePerson.name)
somePerson.name = "qwer"
print(somePerson.name)
@Property Wrapper 키워드를 타입에서 프로퍼티가 해야 할 행동을 정의해준다.
Property Wrapper를 붙여주면 wrappedValue라는 연산 프로퍼티를 내부에 필수로 구현해야 한다.
이렇게 프로퍼티가 해야 할 행동을 정의했다면, 이 행동을 수행할 프로퍼티에 해당 타입의 이름을 부착해준다.
부착만 잘(?) 해주면 별다른 추가 코드 없이, 직접 정의한 Property Wrapper부착 타입의 행동을 프로퍼티가 채택한다.