美文网首页
swift属性包装器 propertyWrapper

swift属性包装器 propertyWrapper

作者: 追忆之丘 | 来源:发表于2021-01-09 10:14 被阅读0次

    swift属性包装器 propertyWrapper

    什么是属性包装器「propertyWrapper」?

    • 在类、结构体或者枚举的声明时使用该特性,可以让其成为一个属性包装器。如果将该特性应用在一个类型上,将会创建一个与该类型同名的自定义特性。将这个新的特性用于类、结构体、枚举的属性,则可以通过包装器的实例封装对该属性的访问。局部和全局变量不能使用属性包装器。

    • 包装器必须定义一个 wrappedValue 实例属性。该属性 wrapped value 是该属性存取方法暴露的值。大多数时候,wrappedValue 是一个计算属性,但它可以是一个存储属性。包装器负责定义和管理其包装值所需的任何底层存储。编译器通过在包装属性的名称前加下划线(_)来为包装器的实例提供同步存储。例如,someProperty 的包装器存储为 _someProperty。包装器的同步存储具有 private 的访问控制级别。

    • 拥有属性包装器的属性可以包含 willSet 和 didSet 闭包,但是不能重写编译器合成的 get 和 set 闭包。

    • Swift 为属性包装器的构造函数提供了两种形式的语法糖。可以在包装值的定义中使用赋值语法,将赋值语句右侧的表达式作为值传递给属性包装器构造函数中的 wrappedValue 参数。同样的,你也可以为包装器提供一些参数,这些参数将会传递给包装器的构造函数。就像下面的例子,SomeStruct 中,定义 SomeWrapper 的地方各自调用了对应的构造函数。

    我们先定义一个Limit的属性包装器,用来限制dog的height和weight

    @propertyWrapper
    struct Limit{
        private var number: Int
        private var maximum: Int
        private var minimum: Int
        
        var projectedValue: String{
            return String(describing: "The value: \(self.number)")
        }
        
        var wrappedValue: Int{
            get { return number }
            set {
                if (minimum...maximum).contains(newValue){
                    number = newValue
                }else{
                    number = minimum
                    print("设置的值不合理,系统已经为您更改为默认的最小值")
                }
            }
        }
        
        init() {
            minimum = 0
            maximum = 0
            number = 0
        }
        
        init(minimum: Int, maximum: Int) {
            self.maximum = maximum
            self.minimum = minimum
            self.number = minimum
        }
        
        init(minimum: Int, maximum: Int, number: Int) {
            self.maximum = maximum
            self.minimum = minimum
            self.number = number
            self.wrappedValue = self.number
        }
    }
    

    然后去使用这个包装器

    struct DogSize{
        @Limit(minimum: 10, maximum: 50) var height: Int
        @Limit(minimum: 0, maximum: 50) var weight: Int
    }
    struct Dog{
        var size: DogSize
        var name: String
    }
    let dogSize = DogSize()
    var dog = Dog(size: dogSize, name: "tom")
    dog.size.height = 500
    print(dog.size.$height)
    print(dog.size.height)
    // 设置的值不合理,系统已经为您更改为默认的最小值
    // The value: 10
    // 10
    

    相关文章

      网友评论

          本文标题:swift属性包装器 propertyWrapper

          本文链接:https://www.haomeiwen.com/subject/uvrfaktx.html