界说

在 Swift 5.1 中引入了@propertyWrapper这个特性,它能够为特点增加一些自界说的行为,从而使代码愈加简练、可读、易于保护。@propertyWrapper是一个特点包装器,能够运用它为特点增加一些自界说的行为。一个特点包装器是一个结构体,用于管理特点的存储和拜访。它能够界说自己的getset方法,并在特点读写时触发自己的逻辑。

作用

@propertyWrapper能够供给以下几个作用:

  • 简化代码:运用@propertyWrapper能够简化代码,减少重复的逻辑
  • 增加可读性:运用@propertyWrapper能够使代码愈加易于阅览和了解,由于它能够供给一些自界说的行为和描绘
  • 优化性能:运用@propertyWrapper能够优化代码的性能,由于它能够控制特点的存储和拜访方式
  • 进步安全性:运用@propertyWrapper能够进步代码的安全性,由于它能够验证特点值的合法性,避免过错的输入

运用场景

@propertyWrapper能够用于以下场景:

  • 验证特点值的合法性,例如规模、格局、唯一性等
  • 处理特点值的改变,例如映射、转化、格局化等
  • 控制特点的存储和拜访方式,例如推迟加载、懒加载、缓存等
  • 完成特点的依靠关系,例如主动更新、主动绑定等

增加验证规矩

@propertyWrapper
struct NonEmptyString {
    private var value: String = ""
    init(wrappedValue: String) {
        if wrappedValue.isEmpty {
            self.value = "Unnamed"
        } else {
            self.value = wrappedValue
        }
    }
    var wrappedValue: String {
        get { value }
        set {
            if !newValue.isEmpty {
                value = newValue
            }
        }
    }
}
struct Person {
    @NonEmptyString var name: String
}
var person1 = Person(name: "") // name will be set to "Unnamed"
var person2 = Person(name: "John") // name will be set to "John"​

上面的比如中,我们运用 NonEmptyString 特点包装器来对 Person 实例的 name 特点进行验证,这使得代码愈加强健和牢靠,避免了一些过错的输入数据

增加缓存功用

@propertyWrapper
class Cached<T> {
    private var value: T
    private var cachedValue: T?
    init(wrappedValue: T) {
        self.value = wrappedValue
    }
    var wrappedValue: T {
        get {
            if let cachedValue = cachedValue {
                return cachedValue
            } else {
                cachedValue = value
                return value
            }
        }
        set {
            value = newValue
            cachedValue = nil
        }
    }
}
class NetworkClient {
    @Cached var data: [String] = []
    func fetchData() { /* ... */ }
} 
var client = NetworkClient()
client.data = ["a", "b", "c"]
print(client.data) // ["a", "b", "c"]

完成主动更新

后续更新

注意事项

  • @propertyWrapper 只能用于特点,不能用于计算特点或许函数
  • @propertyWrapper 能够应用于单个特点或许整个结构体/类中的所有特点
  • 运用 @propertyWrapper 时,需求为包装器供给一个默认值
  • 假如特点包装器需求进行一些额外的初始化,需求运用 init(wrappedValue:) 方法
  • 运用 @propertyWrapper 时,需求为包装器增加 wrappedValue 特点
  • 运用 @propertyWrapper时,需求遵循 Swift 中的命名规范,例如运用驼峰命名法

总结

@propertyWrapper 是 Swift 中非常强大的特性之一,能够用于完成许多常见的功用,例如特点验证、缓存、主动更新等。运用 @propertyWrapper 能够使代码愈加简练、可读、易于保护,由于它将特点包装器和特点自身分离开来,并将某些常见的行为抽象出来