Swift - @propertyWrapper

이한솔·2024년 4월 11일
0

Swift 문법 🍎

목록 보기
31/32

propertyWrapper

propertyWrapper란 Swift 5.1에서 도입된 기능 중 하나로, 속성에 대한 접근 및 저장을 캡슐화하고 수정자를 제공하여 코드를 간소화하고 재사용성을 높이는 데 사용됩니다.

@propertyWrapper
struct Doubled<Value: Numeric> {
    var value: Value

    init(wrappedValue: Value) {
        self.value = wrappedValue * 2
    }

    var wrappedValue: Value {
        get { value }
        set { value = newValue * 2 }
    }
}


struct Number {
    @Doubled var value: Int
}


var number = Number(value: 5)
print(number.value) // 10 출력

number.value = 8
print(number.value) // 16 출력

만약 @propertyWrapper 구조체에 init이 없다면 number의 타입이 Value가 아니라 Doubled타입이 된다.



UserDefaults 예제

class UserManager {
    
    static var usesTouchID: Bool {
        get { return UserDefaults.standard.bool(forKey: "usesTouchID") }
        set { UserDefaults.standard.set(newValue, forKey: "usesTouchID") }
    }
    
    static var myEmail: String? {
        get { return UserDefaults.standard.string(forKey: "myEmail") }
        set { UserDefaults.standard.set(newValue, forKey: "myEmail") }
    }

    static var isLoggedIn: Bool {
        get { return UserDefaults.standard.bool(forKey: "isLoggedIn") }
        set { UserDefaults.standard.set(newValue, forKey: "isLoggedIn") }
    }
}

get/set 구현이 겹치는 부분이 있다. @propertyWrapper를 사용해서 코드를 개선해보자!

@propertyWrapper
struct UserDefault<T> {
    
    let key: String
    let defaultValue: T

    var wrappedValue: T {
        get { UserDefaults.standard.object(forKey: self.key) as? T ?? self.defaultValue }
        set { UserDefaults.standard.set(newValue, forKey: self.key) }
    }
}


class UserManager {
    
    @UserDefault(key: "usesTouchID", defaultValue: false)
    static var usesTouchID: Bool
    
    @UserDefault(key: "myEmail", defaultValue: nil)
    static var myEmail: String?
    
    @UserDefault(key: "isLoggedIn", defaultValue: false)
    static var isLoggedIn: Bool
}

UserDefaults Property Wrapper의 이니셜라이저를 이용하여 기본값을 지정한다.
기존에 있었던 get/set 같은 보일러 플레이트 코드들 없이 동일한 효과를 낼 수 있다.



참고자료
참고
참고2

0개의 댓글