Swift-属性包装器

@propertyWrapper

Swift 提供的一种"属性包装器"机制,用来给属性增加统一的逻辑。

它本质上是:

  • 对属性的"读写行为"进行封装
  • 避免重复代码
  • 增强属性能力(缓存、校验、持久化、线程安全等)

基本用法

场景:希望给标题这个属性,提供自动大写逻辑,每次赋值都需要处理

先定义一个属性包装器。(封装某些处理逻辑)

swift 复制代码
@propertyWrapper
struct Uppercase {
    private var value: String = ""
    var wrappedValue: String {
        get { value }
        set { value = newValue.uppercased() }
    }
}

然后,在需要的地方,修饰属性。(复用代码)

less 复制代码
struct User {

    @Uppercase    // 使用属性包装器 修饰
    var name: String

    ...
}

这样,每次对 name 进行set,都会"继承"自动大写的处理逻辑

其他场景:

  • 限制范围
  • 自动缓存
  • UserDefaults存储
  • 自动日志

带参数的 属性包装器

场景:如,给表示年纪的属性,限制范围。

python 复制代码
@propertyWrapper
struct RangeLimit {

    private var value: Int

    let min: Int
    let max: Int

    init(wrappedValue: Int,
         min: Int,
         max: Int) {

        self.min = min
        self.max = max

        self.value = Swift.max(min,
                               Swift.min(max, wrappedValue))
    }

    var wrappedValue: Int {
        get { value }
        set {
            value = Swift.max(min,
                              Swift.min(max, newValue))
        }
    }
}

使用

less 复制代码
struct User {

    @RangeLimit(min: 0, max: 100)
    var age: Int = 50
}

这样,即使给 user.age = 150 ,其值会限制在 100以内。

Property Wrapper + 泛型

任何类型,都可修饰

swift 复制代码
@propertyWrapper
struct Cache<T> {

    private var value: T

    init(wrappedValue: T) {
        self.value = wrappedValue
    }

    var wrappedValue: T {
        get { value }
        set {
            // ....
            value = newValue 
        }
    }
}

常见使用场景

1、封装UserDefault

vbnet 复制代码
@propertyWrapper
struct UserDefault<T> {

    let key: String
    let defaultValue: T

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

struct UserDefaultConfig {

    @UserDefault(key: "token", defaultValue: "")
    static var token: String
    
    ...
}

使用

ini 复制代码
UserDefaultConfig.token = "abc"
相关推荐
风骏时光牛马1 分钟前
AI_Coding:智能代码创作助手
前端
剪刀石头布啊9 小时前
vue-react为何要虚拟dom
前端
剪刀石头布啊9 小时前
ahooks常用的一些库,我们使用一下
前端
剪刀石头布啊9 小时前
从git更新本地提交记录到更新已经推送到远端记录
前端
Flynt11 小时前
axios 被投毒半年后,我把 npm 的"安全防线"实测了一遍:最信任的 SHA512 是安慰剂
前端·npm·node.js
excel12 小时前
Base62 和 Base64 有什么区别?
前端
风骏时光牛马13 小时前
大模型底层架构与AI源码深度剖析
前端
掘金挖土14 小时前
前端手摸手跑路之 AI 应用开发(九)
前端·后端
中文呀16 小时前
三维 GIS 离线缓存实战:逆向 CesiumOfflineCache,并亲手为它补上"自动更新"能力
前端