iOS开发 - 「Swift 学习」Swift属性包装器@propertyWrapper(一)

定义:

在 Swift 5.1 中引入了@propertyWrapper这个特性,属性包装器是在 管理属性存储方式的代码和定义属性的代码之间添加了一层分离。管理属性的setget方式由属性包装器接管,定义属性的代码还在原来的类中。**

参考来源 →

作用:

如果你有属性提供了线程安全检查或将数据存到数据库功能,那么你将需要为每个属性编写类似代码。有了属性包装器,我们就可以避免类似重复代码。

使用场景:

▪验证属性值的合法性,例如范围、格式、唯一性等;
▪处理属性值的变化,例如映射、转换、格式化等;
▪控制属性的存储和访问方式,例如延迟加载、懒加载、缓存等;
▪实现属性的依赖关系,例如自动更新、自动绑定等。

实现:

通过 @propertyWrapper来标识struct, enum, class实现属性包装。

要点:

▪必须使用属性@propertyWrapper进行定义;
▪必须为包装器添加 wrappedValue 属性;
▪@propertyWrapper 只能用于属性,不能用于计算属性或者函数;
▪@propertyWrapper 可以应用于单个属性或者整个结构体/类中的所有属性;
▪使用 @propertyWrapper 时,需要为包装器提供一个默认值;
▪如果属性包装器需要进行一些额外的初始化,需要使用 init(wrappedValue:) 方法。

结构示例:

@propertyWrapper
 struct NumberWrapper {    
     private var value: Int = 0
     var wrappedValue: Int {
         get {
             return value
         }
         set {
             //  value <= 10
             value = min(newValue, 10)
         }
     }
 }
 

struct Number {
    // 告诉编译器使用Wrapper包装器包装该属性
    @NumberWrapper var number: Int
}

调用分析:
使用@NumberWrapper时编译器会转为下面的执行过程

struct Number {
    private var _number = NumberWrapper()
 
    var number: Int {
        get { return _number.wrappedValue }
        set { _number.wrappedValue = newValue }
    }
}

▪调用 Number 中number 的 set 函数
▪调用 属性包装器的 _number.wrappedValue 的 set函数
▪调用 number = min(newValue, 10) 来保证新设置的值小于等于 10

使用限制:

  • 协议的属性不支持使用属性包装器
  • extension中不可以使用(扩展内声明的非静态属性不能有包装器)
  • enum中不可以使用(属性包装器只能应用于属性)
  • class里的 wrapper property 属性不能被重写
  • wrapper 不能定义 getter 或 setter 方法 ( 属性包装器不能应用于计算属性)
  • wrapper 属性不能被 lazy、 @NSCopying、 @NSManaged、 weak、 或者 unowned 修饰

下一篇:iOS开发 - 「Swift 学习」Swift属性包装器@propertyWrapper 投影值 projectedValue(二)


\color{gray}{欢迎大佬儿来指正纠错,共同学习😏!!}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容