Swift 之 Property Wrappers 特性

Swift 5.1 新增了 Property Wrappers 特性。该特性可以通过使用 @ 符号以注解的形式来实现某些功能,并达到简化代码的效果。

示例

iOS 中的 UserDefaults 为例,一般用法如下。

  • 存储数据
UserDefaults.standard.set(value, forKey: key)
  • 获取数据
UserDefaults.standard.object(forKey: key)

改造

Property Wrappers 需满足两个基本要求:

  • 必须使用 @propertyWrapper 关键字来修饰。
  • 必须有一个命名为 wrappedValue 的属性。

接下来以 Property Wrappers 方式改造 UserDefaults ,代码如下:

@propertyWrapper
struct MyUserDefault<T> {

    let key: String
    let defaultValue: T

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

}

使用

@MyUserDefault(key: "username", defaultValue: "")
static var username: String

加了 MyUserDefault 自定义注解后,对 username 的赋值操作相当于是执行了 UserDefaults.standard.set 方法,对 username 的读取操作相当于执行了 UserDefaults.standard.object 方法。

限制

Property Wrappers 也有一些使用上的限制。比如:

  • 无法在 protocol 中进行声明。
  • 通过 wrapper 包装的实例属性(An instance property with a wrapper)无法在 extension 中进行声明。
  • 无法在 enum 中进行声明。
  • class 中通过 wrapper 包装的属性无法被另外一个属性通过 override 覆盖掉。
  • 通过 wrapper 包装的实例属性(An instance property with a wrapper)不能用 lazy@NSCopying@NSManagedweakunowned 来修饰。

继续阅读“Swift 之 Property Wrappers 特性”