Swift属性包装器的使用

从Swift5.0开始,Swift引入了属性包装器(propertyWrapper),这应该算是苹果原生应用开发上的一次技术思想的突破吧。即便功能限制性很多,但也为我们解决一些问题带来了方便。比如,我们现在要限制一些数值的取值范围的话,在Objc时代,甚至是Swift早些时候。我们要想要实现这种方法,那么久的在赋值或者取值的过程中进行判断。这从代码上来讲还是侵入性比较强的。但是在Swift5.0引入属性包装器之后,这类问题就得到了解决。下面我们就来一步步了解属性包装器的使用吧。

为了更好的来讨论,我们先设定一个场景:在一个用户信息系统中,我们要存储用户的基本信息,但是要求用户信息中的年龄字段取值只能在0~之间,如果年龄大于则取,小于0则取0,要求使用的时候要保证数据取值的安全性。这个问题我们应该怎么解决呢?

在属性包装器概念引入之前,为了数据的安全性我们基本上在每个使用到年龄大地方,都要写一大堆保护性代码,或者调用一个专门的封装函数来进行处理,如果涉及到某些地方用年龄来过滤或做表,可能还存在一些其他更复杂的问题。当然,为了统一,我们可能会写一个如下的方法:

funcfixAge(age:Int)-Int{

ifage{

return

}

ifage0{

return0

}

returnage

}

在使用的时候通过fixAge(age:)调用来达到数据修正的目的。但是,这是一个好办法么?如果我们从代码侵入性角度来看肯定是不好的。下面,我们用属性包装器来实现:

propertyWrapper

structAgeWrapper{

varwrappedValue:Int{

get{

returnage

}

set{

ifnewValuemax{

age=max

}elseifnewValuemin{

age=min

}else{

age=newValue

}

}

}

varage:Int=0

varmin:Int

varmax:Int

init(min:Int,max:Int){

self.min=min

self.max=max

}

}

接下来,我们再来定义变量age

AgeWrapper(min:0,max:)varage:Int

并给一个调用的实例如下:

print("oldvalue-\(age)")

age=

print("newvalue-\(age)")

运行代码会得到如下运行结果

oldvalue-0

newvalue-

好想,我们在使用的时候,完全没有做任何修正,但是我们前面的目的已经达到了。不仅如此,为了实现对年龄限制的的通用性,我们对属性包装器做如下修改:

propertyWrapper

structAgeWrapper{

varwrappedValue:Int{

get{

returnage

}

set{

age=limitHandle(newValue)

}

}

varage:Int=0

varlimitHandle:(Int)-Int

init(limithandle:

escaping(Int)-Int){

self.limitHandle=handle

}

}

并将初始化修改如下:

AgeWrapper(limit:{max(0,min($0,))})varage:Int

继续运行执行结果,我们会发现,执行的结果与之前是一致的。而且这个包函数也变的更灵活了。

有了一个真实的案例,回过来在看看属性包装器的实现逻辑:

1.属性包装器的定义基于一个被

propertyWrapper修饰的struct或class的;

2.属性包装起有一个必须实现一个名为wrappedValue的属性;该属性实际负责对真实数据进行修正处理

3.在使用定义的属性包装器时,将

属性包装器放在需要修饰的属性前即可;

4.最后就是使用被修饰的变量,只需按照我们正常的使用变量的方式使用即可。

回过头来想想,属性包装器,对于我们已有的未做数据安全保护的代码,是不是现在要进行数据安全性保护的话,将变得更容易呢?




转载请注明:http://www.aierlanlan.com/rzgz/6493.html