美文网首页
Swift中属性包装器@propertyWrapper

Swift中属性包装器@propertyWrapper

作者: Sweet丶 | 来源:发表于2023-05-06 18:17 被阅读0次

    @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

    相关文章

      网友评论

          本文标题:Swift中属性包装器@propertyWrapper

          本文链接:https://www.haomeiwen.com/subject/lzucsdtx.html