swift 中属性包装器的使用说明

  • Post author:
  • Post category:其他




1. 什么是 @propertyWrapper

这是用来定义一个属性包装器结构的关键字.



2. @propertyWrapper使用方式

@propertyWrapper
struct LimitNumber {
...
}



3. 属性包装有什么用处

大体来说主要有几个用处:限制边界,减少错误,编码简洁,可读性更好。



4. 如何使用-举例说明

首先定义了一个用来存放数值的类型,但是该类型的数值是有范围要求的。

//该struct用来存放可以限制范围的数值
@propertyWrapper
struct LimitNumber {
    private var _number:Int
    private var _maximum:Int
    private var _minimum:Int
    
    var projectedValue = "我是映射值:projectedValue" //该变量名固定 可以用$访问
    //属性包装的结构体中,必须存在一个名为wrappedValue的属性
    var wrappedValue: Int { //该属性名称固定,必须存在
        get {return _number}
        set {
            print("LimitNumber: wrappedValue setter ...max=\(_maximum),min=\(_minimum),num=\(_number),newValue=\(newValue)")
            if(_minimum..._maximum).contains(newValue){
                _number = newValue
            } else {
                print("WARNING:给定数值:\(newValue) ,超出范围限制\(_minimum)...\(_maximum), 已被忽略。")
            }
        }
    }
    
    init() {
        print("LimitNumber: init()")
        _maximum = 10
        _minimum = 0
        _number = 0;
    }
    
    init(minimum:Int,maximum:Int) {
        print("LimitNumber: init(minimum:\(minimum),maximum:\(maximum))")
        _maximum = maximum
        _minimum = minimum
        _number = minimum;
    }
    
    init(minimum:Int,maximum:Int,number:Int) {
        print("LimitNumber: init(minimum:Int,maximum:Int,number:Int)")
        _maximum = maximum
        _minimum = minimum
        _number = minimum; //如果不为_number初始化值,使用self会出错:self used before all stored properties are initialized
        self.wrappedValue = number;
    }
}

接下来定义一个类型,用来表示一个人的身高和体重, 并且使用上面已经定义的属性包装器来限制数值的范围。

struct PersonSize {
    //使用包装属性限制身高的可设定范围
    @LimitNumber(minimum: 29, maximum: 230) var height: Int {
        willSet{print("PersonSize->height->willSet")}
    }
    
    //使用包装属性限制体重的可设定范围
    @LimitNumber(minimum: 2, maximum: 1000) var weight: Int{
        willSet{print("PersonSize->weight->willSet")}
    }
}

现在这个PersonSize类型就可以使用了

//struct 会自动生成隐式的初始化函数 Person(size: PersonSize, name: String)
struct Person {
     var size:PersonSize
     var name:String
}

let size = PersonSize()
var p1 = Person(size: size, name: "jone")

p1.size.height = 180
p1.size.weight = 1
p1.size.weight = 90
print(p1.size.$height) //此处为映射值的测试代码

运行执行结果如下:

LimitNumber: init(minimum:29,maximum:230)
LimitNumber: init(minimum:2,maximum:1000)
PersonSize->height->willSet
LimitNumber: wrappedValue setter ...max=230,min=29,num=29,newValue=180
PersonSize->weight->willSet
LimitNumber: wrappedValue setter ...max=1000,min=2,num=2,newValue=1
WARNING:给定数值:1 ,超出范围限制2...1000, 已被忽略。
PersonSize->weight->willSet
LimitNumber: wrappedValue setter ...max=1000,min=2,num=2,newValue=90
我是映射值:projectedValue

你们觉得这个图片我用手机拍的效果怎么样?



!!!

在这里插入图片描述



版权声明:本文为xuanwenchao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。