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"
相关推荐
FungLeo29 分钟前
成为全栈·React 管理后台篇·总复盘:从“接口能调通”到“后台值得使用”
前端·react.js·前端框架·项目复盘·成为全栈
Csvn2 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_2 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt2 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide3 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel3 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘5 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马5 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut5 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
hiahiahia1235 小时前
实现完整 Tool Dispatcher
开发语言·前端