What is '@propertyWrapper' in Swift
@propertyWrapper
propertyWrapper는 프로퍼티가 저장되는 방식을 관리하는 코드와 프로퍼티를 정의하는 코드 사이에 분리 계층을 추가한다.
예를 들어, 기본 데이터를 UserDefaults에 저장해야 하는 여러 가지 프로퍼티가 있는 경우 모든 프로퍼티에 UserDefaults를 관리하는 코드를 작성해야 하는데
propertyWrapper를 사용할 경우 UserDefaults 관리 코드를 한 번 작성한 다음 여러 프로퍼티에 재사용할 수 있다.
Apply
propertyWrapper는 프로퍼티가 저장되는 방식을 관리하는 코드와 프로퍼티를 정의하는 코드 사이에 분리 계층을 추가한다.
예를 들어, 기본 데이터를 UserDefaults에 저장해야 하는 여러 가지 프로퍼티가 있는 경우 모든 프로퍼티에 UserDefaults를 관리하는 코드를 작성해야 하는데
propertyWrapper를 사용할 경우 UserDefaults 관리 코드를 한 번 작성한 다음 여러 프로퍼티에 재사용할 수 있다.
Declaration Attributes 중 하나인 propertyWrapper를 클래스, 구조체 또는 열거형 Declaration에 적용하면 해당 타입을 propertyWrapper로 사용할 수 있다.
@propertyWrapper
struct SomeWrapper {
}
propertyWrapper를 타입에 적용하면 해당 타입과 이름이 같은 사용자 정의 attribute가 생성된다.
@SomeWrapper
타입의 프로퍼티를 래핑하기 위해서는 생성된 attribute를 프로퍼티에 적용해야 한다.
struct SomeStruct {
@SomeWrapper var someValue: Int
}
⚠️ Computed variables, global variables, and constants can’t use property wrappers.
WrappedValue
wrapper에는 반드시 wrappedValue 인스턴스 프로퍼티를 정의해야 한다. 타입의 프로퍼티에 래핑되는 값은 wrappedValue의 getter & setter로 노출되는 값이다.
(대부분의 경우 wrappedValue는 계산된 값이지만 저장된 값으로도 사용할 수 있다.)
@propertyWrapper
struct SomeWrapper {
private var someValue = 0
var wrappedValue: Int {
get {
return someValue
}
set {
someValue = newValue
}
}
}
Synthesized Storage
propertyWrapper는 래핑된 값에 필요한 기본 저장소를 정의하고 관리할 수 있다. 컴파일러는 래핑된 타입의 이름에 underscore(_)를 접두사로 붙여 wrapper 타입의 인스턴스에 대한 저장소를 합성한다.
propertyWrapper에 대한 합성 저장소에는 private 수준의 접근 제어를 적용해야 한다.
struct SomeStruct {
private var _someValue = SomeWrapper()
var someValue: Int {
get {
return _someValue
}
set {
_someValue = newValue
}
}
}
@propertyWrapper 초기화
Swift는 propertyWrapper의 초기화를 위해 두 가지 형태의 구문을 제공한다.
@propertyWrapper
struct SomeWrapper {
var wrappedValue: Int
init() {
self.wrappedValue = 10
}
init(wrappedValue: Int) {
self.wrappedValue = wrappedValue
}
}
예를 들어, SomeStruct는 SomeWrapper가 정의하는 초기화를 호출한다.
struct SomeStruct {
// Uses init()
@SomeWrapper var a: Int /// -> 10
// Uses init(wrappedValue:)
@SomeWrapper var b = 100 /// -> 100
@SomeWrapper(wrappedValue: 999) var c: Int /// -> 999
}
Projected Value
wrapped property에 대한 projected value는 wrapped property가 추가 기능을 표시하는 데 사용할 수 있는 두 번째 값이다. wrapped property의 이름에 dollar sign ($)을 접두사로 붙여 호출하면 projected value에 접근할 수 있다.
projected value는 original wrapped property와 동일한 접근 제어 수준을 갖는다.
Example. Use Projected Value
Projected Value를 사용하면 정규성 검사를 통과하지 못한 번호가 무엇인지 확인할 수 있다.
@propertyWrapper
struct PhoneNumber {
private var phone = ""
var projectedValue: String?
var wrappedValue: String {
get { return phone }
set {
projectedValue = validate(newValue) ? nil : newValue
phone = validate(newValue) ? newValue : "Invalid PhoneNumber"
}
}
init(wrappedValue: String) {
self.wrappedValue = wrappedValue
}
private func validate(_ phoneNumber: String) -> Bool {
let validFormat = "^01[0-1, 7][0-9]{7,8}$"
let phoneNumberPredicate = NSPredicate(format: "SELF MATCHES %@", validFormat)
return phoneNumberPredicate.evaluate(with: phoneNumber)
}
}
struct User {
@PhoneNumber var phone: String
}
let user = User(phone: "01012345678")
user.phone /// -> "01012345678"
user.$phone /// -> nil
let user = User(phone: "12345678")
user.phone /// -> "Invalid PhoneNumber"
user.$phone /// -> "12345678"
cf.
https://docs.swift.org/swift-book/ReferenceManual/Attributes.html
Author And Source
이 문제에 관하여(What is '@propertyWrapper' in Swift), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@haanwave/what-is-propertyWrapper-in-Swift저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)