Swift中属性包装器@propertyWrapper

@propertyWrapper是我们比较少用到的技术点,但项目中有用到,所以还是得学习下,偷懒总是不对的。

一、问题引入

如果我们需要在UserDefaults中存一个是否首次启动的值,需要这样写:

enum Keys {
    static let isFirstLaunch = "isFirstLaunch"
}
extension UserDefaults {
    var isFirstLaunch: Bool {
        get {
            return bool(forKey: Keys.isFirstLaunch)
        }
        set {
            set(newValue, forKey: Keys.isFirstLaunch)
        }
    }
}

如果这样属性有很多,就需要写大量的get 、set方法,那么有没有办法能不能简化这一系列很类似的写法呢?
答案是有的,就是@propertyWrapper.

二、@propertyWrapper的使用

@propertyWrapper的意思就是属性包装,它可以将一系列相似的属性方法进行统一处理。比如上述的例子,我们使用@propertyWrapper可以这样写:

// 1. 先定义一个属性包装器
@propertyWrapper
struct UserDefaultWrapper<T> {
    private let key: String
    private let defaultValue: T
    init(key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }
  
    var wrappedValue: T {
        get {
            UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}
// 2. 再定义需要的包装的属性
extension UserDefaults {
    @UserDefaultWrapper(key: Keys.isFirstLaunch, defaultValue: false)
    static var isFirstLaunch: Bool
}

// 3. 使用的地方就变得很简单了
UserDefaults.isFirstLaunch = true // 存值
print(UserDefaults.isFirstLaunch) // 取值
三、进一步了解@propertyWrapper

属性包装器既可以作用于计算属性又可以作用于静态计算属性

@propertyWrapper
struct Wrapper<T> {
    var wrappedValue: T

    var projectedValue: Wrapper<T> { return self }

    func foo() { print("Foo") }
}
struct HasWrapper {
    @Wrapper var x = 0
    
    func foo() {
        print(x) // 0
        print(_x) // Wrapper<Int>(wrappedValue: 0)
        print($x) // Wrapper<Int>(wrappedValue: 0)
     }
    
    @Wrapper static var y = 0
    static func foo2() {
        print(y) // 0
        print(_y) // Wrapper<Int>(wrappedValue: 0)
        print($y) // Wrapper<Int>(wrappedValue: 0)
     }
}

// 测试代码
HasWrapper.foo2()
HasWrapper().foo()

更深入了解可参考:Swift Property Wrappers

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容