Swift @propertyWrapper(属性包装)的使用和本质

Posted Jsen_Wang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift @propertyWrapper(属性包装)的使用和本质相关的知识,希望对你有一定的参考价值。

什么是@propertyWrapper(属性包装)

1,它类似Java等语言中的注解
2,它包装修饰属性的get set方法
3,目的在于封装属性操作,简化代码,降低重复书写概率

@propertyWrapper什么作用

预设场景

实际开发中,我们的默一个属性要求必须为两头去除空格的状态.
这时我们有两种方式实现
1, 重写get方法,每次get时都去除两头空格
2, 重写set方法,每次set时都去除两头空格
(对于以上方法,我们暂不讨论性能和业务贴合的问题.)

class Test 
    var whiteStr 
		set 
			// 去除空格操作
		
		// 或者
		get 
			// 去除空格操作
		
	


这时我们会面临一个问题,如果有很多个属性都有这个要求
那么我们的代码就会变成

class Test 
    var whiteStr1 
		set 
			// 去除空格操作
		
		// 或者
		get 
			// 去除空格操作
		
	
	
    var whiteStr2 
		set 
			// 去除空格操作
		
		// 或者
		get 
			// 去除空格操作
		
	
	...

充其量我们把“去除空格操作”抽象提取出来,但也并不能降低多少代码重复率,还是在不停的写set get

这时@propertyWrapper的作用就提现出来了

它可以以下形式来编写:

class Test 
	@NoWhite() //“NoWhite”这个名字是我们自己定义的
    var whiteStr1 
    
	@NoWhite()
    var whiteStr2
    
	...

并且可以达到同样去除两头空格目的

@propertyWrapper怎么实现及实践

@propertyWrapper struct NoWhite 
    // 用来记录被包装属性的值
    // 可以是别的名字,比如model item等,value只是在此demo中的名字
    var value: String
    
    // 包装值,可以把它看成value的计算属性
    // 'wrappedValue' 这个名称不能更改,必须实现
    // 以上一段中的`whiteStr`为例
    // 被NoWhite修饰后, 操作`whiteStr`对应的get set 方法,实际是在操作wrappedValue的
    // get set 方法
    // 这里我们选用在set中处理两头空格的方式
    var wrappedValue: String 
        get  value 
        set 
            let whitespace = NSCharacterSet.whitespacesAndNewlines
            value = newValue.trimmingCharacters(in: whitespace)
        
    
    
    //  映射值
    //  被修饰的属性在属性名前加`$`符,调用的就是的projectedValue的get方法
    //  比如, self.$whiteStr
	//  当使用self.$whiteStr作为参数传递时,是引用传递. 
	//  使用self.whiteStr作为参数传递时,是值传递
 	var projectedValue: String 
        let whitespace = NSCharacterSet.whitespacesAndNewlines
        return value.trimmingCharacters(in: whitespace)
    
    
    // 初始化方法
    init(wrappedValue initialValue: String = "") 
        value = initialValue
    



class Test 
    @NoWhite()
    var whiteStr


te.whiteStr = " 123 " // 首位有空格

print(te.whiteStr) // "123"

print(te.whiteStr.count) // "3"

总结

1, @propertyWrapper的本质就是包装修饰属性的set get方法
2, @propertyWrapper的作用就是降低代码重复率
3, @propertyWrapper的应用中的projectedValue在SwiftUI的 @State中, 作为 @Binding 的修饰对象的引用传递来解决多层嵌套UI的状态同步问题.

以上是关于Swift @propertyWrapper(属性包装)的使用和本质的主要内容,如果未能解决你的问题,请参考以下文章

Swift @propertyWrapper(属性包装)的使用和本质

Swift | 属性包装器

@State实现原理以及自我实现@State功能

swift结构体和类属性-005-swift类结构体基本属性

Swift:计算属性的属性观察者

Swift属性