包装类属性类型数据
Property wrapper adds a wrapper over a property which stores it and defines how the property will behave
属性包装器为存储属性的属性添加了一个包装器,并定义了该属性的行为
As the name suggests its a wrapper over the property, so you can fiddle with the raw value before returning it. Property wrappers can be used with struct
enum
and class
.
顾名思义,它是对属性的包装,因此您可以在返回原始值之前先弄乱原始值。 属性包装器可以与struct
enum
和class
。
You must have seen and even used @State
, @Binding
, @Published
, @ObservedObject
and a lot more in SwiftUI
which highly relies on Property Wrapper
.
你一定见过,甚至使用@State
, @Binding
, @Published
, @ObservedObject
在SwiftUI
还有很多SwiftUI
,高度依赖Property Wrapper
。
We will implement a Music Rating app where a user can rate the music from 1 to 5. If a user mistakenly sets the value greater than 5 (which means he really liked the music) we reset the value to 5 which is the highest rating. Similarly, if he disliked the music and set the value to 0, we reset the value to 1 which is the lowest possible rating.
我们将实现一个“音乐评分”应用程序,用户可以在其中将音乐的评分从1到5。如果用户错误地将值设置为大于5(表示他真的很喜欢音乐),我们会将值重置为最高评分5。 同样,如果他不喜欢音乐并将其值设置为0,我们会将值重置为1,这是可能的最低评分。
![Image for post](https://miro.medium.com/max/9999/0*FegiIUs71LFbXD5P.jpeg)
定义属性包装器: (Defining a property wrapper:)
Prefix the keyword
@properyWrapper
before the struct, enum, or class. We have created a struct Rating and prefixed@properyWrapper
beforestruct
Rating.在结构,枚举或类之前添加关键字
@properyWrapper
。 我们创建了一个结构等级,并在struct
等级之前添加了@properyWrapper
前缀。Property wrapper must contain a non-static property named
wrappedValue
. You can use the getter and setter methods to perform your checks and validations for the variables.属性包装器必须包含一个名为
wrappedValue
的非静态属性。 您可以使用getter和setter方法执行对变量的检查和验证。
用法: (Usage:)
To use the property wrapper, you prefix the wrapper’s name before the property as an attribute. We have prefixed
@Rating
that goes before the attributerating
.要使用属性包装器,您可以在属性之前将包装器的名称作为属性添加前缀。 我们在属性
rating
之前添加了@Rating
前缀。To use the variable just set the attribute value. If you set the value, the
wrappedValue
setter gets called where validation is performed. If the newValue is higher than 5 then the rating is reset to 5. Similarly, when the user sets the value smaller than 1, it reset to 1.要使用变量,只需设置属性值。 如果设置该值,
wrappedValue
在执行验证的位置调用wrappedValue
的值设置器。 如果newValue大于5,则等级将重置为5。类似地,当用户将值设置为小于1时,它将重置为1。
Simple enough! Let’s take a more practical example.
很简单! 让我们举一个更实际的例子。
在包装的属性上设置初始值 (Setting Initial Values on Wrapped Properties)
Hardcoding the maximum and minimum ratings is not the right way to do it. So we will be passing the max and min ratings to the initializer. As you can see in the below code, we have added multiple initializers.
硬编码最大和最小额定值不是正确的方法。 因此,我们会将最大和最小额定值传递给初始化程序。 如下面的代码所示,我们添加了多个初始化程序。
Let’s understand how initializers are called on PropertyWrappers.
让我们了解如何在PropertyWrappers上调用初始化程序。
When you don’t specify an initial value for a property
init()
is called where we set the max, min, and default rating.当您不为属性指定初始值时,将调用
init()
来设置最大值,最小值和默认等级。
// calls init()
@Rating var masakali: Int
2. When you specify an initial value for a property init(wrappedValue:)
is called. You can set the wrapped value in two ways. The first one by assigning value to it. The second way is by adding arguments after they attribute.
2.在为属性指定初始值时,将调用init(wrappedValue:)
。 您可以通过两种方式设置包装值。 第一个通过为其赋值。 第二种方法是在属性后添加参数。
Wattribute you basically call the initializer which accepts those arguments.
w ^ 您基本上调用初始化器的属性 接受这些论点。
struct MusicRating {
// calls init(wrappedValue:)
@Rating var masakali: Int = 5
@Rating (wrappedValue: 5) var masakali: Int
}
3. On similar principles, we can have more than one argument in initializers. When you write parameters in the parentheses after attribute init(wrappedValue: maxRating: minRating:)
gets called.
3.根据相似的原理,我们在初始化器中可以有多个参数。 当在属性init(wrappedValue: maxRating: minRating:)
之后的括号中写入参数时。
struct MusicRating {
// calls init(wrappedValue: maxRating: minRating:)
@Rating (maxRating: 5, minRating: 1) var masakali: Int = 5
@Rating (wrappedValue: 0, maxRating: 5, minRating: 1) var masakali: Int
}
属性包装中的预计值 (Projected value in a property wrapper)
You can add additional functionality on property wrapper using projected values
. The name of the projected value will be similar to wrapped value and can be accessed by appending a $
sign before the wrapped value.
您可以使用projected values
在属性包装器上添加其他功能。 预计值的名称将与包装值相似,并且可以通过在包装值之前附加$
符号来访问。
Projected values are optional to implement and could be used if you add some extra information along with the wrapped value. In the below implementation the projected value returns the number of stars on the rating given by the user.
投影值是实现的可选选项,如果您在包装值中添加了一些额外的信息,可以使用投影值。 在以下实现中,预计值返回用户给定等级上的星数。
将UserDefaults与属性包装器一起使用 (Using UserDefaults with property wrapper)
UserPreferences
is a property wrapper that helps to save and get values from UserDefaults.
UserPreferences
是一个属性包装器,有助于保存和从UserDefaults获取值。
将UserDefaults与属性包装器一起使用 (Using UserDefaults with property wrapper)
UserPreferences
is a property wrapper that helps to save and get values from UserDefaults.
UserPreferences
是一个属性包装器,有助于保存和从UserDefaults获取值。
使用SecureDefaults存储安全对象 (Using SecureDefaults to store Secure object)
SecureDefaults
can be used to wrap the objects confirming to SecureCoding into and from UserDefaults
.
SecureDefaults
可用于将确认SecureCoding的对象包装到UserDefaults
或从UserDefaults
。
That’s pretty much what propertyWrapper
is all about. One of the features I will be using extensively in my projects and will be updating the same blog. do you have a use case that you think should be mentioned here? Let me know down in the comments!
这几乎就是propertyWrapper
的全部用途。 我将在项目中广泛使用的功能之一,并将更新同一博客。 您是否有一个用例,您认为应该在这里提及? 让我在评论中知道!
在此处阅读更多有关Property Wrappers的信息 (Read more around Property Wrappers here)
翻译自: https://medium.com/flawless-app-stories/understanding-property-wrapper-cadf1bc12005
包装类属性类型数据