Swift property
Swift properties associate values with specific classes, structures, or enumerations.
Properties can be divided into storage properties and calculated properties:
Store properties | The calculated property |
---|---|
Store constants or variables as part of an instance | Calculate, rather than store, a value |
For classes and structures | For classes, structures, and enumerates |
Stored and calculated properties are typically used for specific types of instances.
Properties can also be used directly for the type itself, which is called a type property.
In addition, you can define a property observer to monitor changes in property values to trigger a custom action. P roperty watchers can be added to stored properties that they write themselves, or to properties inherited from the parent class.
Store properties
Simply put, a storage property is a constant or variable stored in an instance of a particular class or structure.
Storage properties can be variable store properties (defined by keyword var) or constant storage properties (defined by keywordlets).
-
You can specify a default value when you define a storage property
-
You can also set or modify the value of a storage property during construction, or even the value of a constant storage property
import Cocoa struct Number { var digits: Int let pi = 3.1415 } var n = Number(digits: 12345) n.digits = 67 print("\(n.digits)") print("\(n.pi)")
The output of the above program execution is:
67 3.1415
Consider the following code:
let pi = 3.1415
Pi in the code specifies the default value when defining the storage property (pi s 3.1415), so it doesn't change whenever you instantiate the structure.
If you define a constant storage property, if you try to modify it, you will report an error, as follows:
import Cocoa struct Number { var digits: Int let numbers = 3.1415 } var n = Number(digits: 12345) n.digits = 67 print("\(n.digits)") print("\(n.numbers)") n.numbers = 8.7
The above procedure, the execution will report an error, the error is as follows:
error: cannot assign to property: 'numbers' is a 'let' constant n.numbers = 8.7
Meaning 'numbers' is a constant and you can't modify it.
Delayed storage properties
A deferred storage property is a property whose initial value is calculated the first time it is called.
Use lazy to indicate a deferred storage property before the property is declared.
Attention:
The deferred storage property must be declared as a variablevar
keyword) because the value of the property may not be available until the instance construction is complete. T he constant property must have an initial value before the construction process is complete, so it cannot be declared a deferred property.
Deferred storage properties are typically used to:
-
Delay the creation of the object.
-
When the value of a property depends on other unknown classes
import Cocoa class sample { lazy var no = number() // `var` 关键字是必须的 } class number { var name = "W3CSchool Swift 教程" } var firstsample = sample() print(firstsample.no.name)
The output of the above program execution is:
W3CSchool Swift 教程
Instantify the variable
If you have Objective-C experience, you should know that Objective-C provides two methods for class instances to store values and references. For properties, you can also use instance variables as back-end storage for property values.
These theories are implemented uniformly with attributes in the Swift programming language. P roperties in Swift do not have corresponding instance variables, and the back-end storage of properties is not directly accessible. This avoids the hasse of access in different scenarios and simplifies the definition of properties into a statement.
All information about properties in a type, including naming, type, and memory management characteristics, is defined in a unique place (in the type definition).
The calculated property
In addition to storing properties, classes, structures, and enumerations can define calculated properties that do not store values directly, but provide a getter to get values, and an optional setter to indirectly set the values of other properties or variables.
import Cocoa class sample { var no1 = 0.0, no2 = 0.0 var length = 300.0, breadth = 150.0 var middle: (Double, Double) { get{ return (length / 2, breadth / 2) } set(axis){ no1 = axis.0 - (length / 2) no2 = axis.1 - (breadth / 2) } } } var result = sample() print(result.middle) result.middle = (0.0, 10.0) print(result.no1) print(result.no2)
The output of the above program execution is:
(150.0, 75.0) -150.0 -65.0
If the setter of the calculated property does not define a parameter name that represents the new value, you can use the default name newValue.
Read-only calculation properties
Only getter does not have setter's calculated property, which is read-only.
Read-only calculated properties always return a value that can be passed through the point (.) Operator access, but cannot set a new value.
import Cocoa class film { var head = "" var duration = 0.0 var metaInfo: [String:String] { return [ "head": self.head, "duration":"\(self.duration)" ] } } var movie = film() movie.head = "Swift 属性" movie.duration = 3.09 print(movie.metaInfo["head"]!) print(movie.metaInfo["duration"]!)
The output of the above program execution is:
Swift 属性 3.09
Attention:
Calculated
var
be defined using the var keyword, including read-only calculation properties, because their values are not fixed.let
keyword is used only to declare constant properties, representing values that cannot be modified after initialization.
Property observer
Property watchers monitor and respond to changes in property values, calling property observers every time a property is set, even when the new value is the same as it is today.
You can add property observers to storage properties other than deferred storage properties, or you can add property observers to inherited properties, including storage properties and calculated properties, by overloading properties.
Attention:
You do not need to add a property observer to a calculated property that cannot be overloaded, because changes in values can be monitored and responded to directly through setter.
You can add one or all of the following observers to the property:
-
willSet
called before setting a new value -
didSet
called as soon as the new value is set - WillSet and didSet observers are not called during property initialization
import Cocoa class Samplepgm { var counter: Int = 0{ willSet(newTotal){ print("计数器: \(newTotal)") } didSet{ if counter > oldValue { print("新增数 \(counter - oldValue)") } } } } let NewCounter = Samplepgm() NewCounter.counter = 100 NewCounter.counter = 800
The output of the above program execution is:
计数器: 100 新增数 100 计数器: 800 新增数 700
Global and local variables
The patterns described by the Calculated Properties and Property Observer can also be used for global and local variables.
The local variable | Global variable |
---|---|
A variable defined inside a function, method, or closure. | Functions, methods, closures, or variables defined outside of any type. |
Used to store and retrieve values. | Used to store and retrieve values. |
Storage properties are used to get and set values. | Storage properties are used to get and set values. |
It is also used to calculate properties. | It is also used to calculate properties. |
Type property
A type property is written in parentheses at the outerst layer of a type as part of a type definition.
Use the keyword static to define the type properties of the value type, and the keyword class to define the type properties for the class.
struct Structname { static var storedTypeProperty = " " static var computedTypeProperty: Int { // 这里返回一个 Int 值 } } enum Enumname { static var storedTypeProperty = " " static var computedTypeProperty: Int { // 这里返回一个 Int 值 } } class Classname { class var computedTypeProperty: Int { // 这里返回一个 Int 值 } }
Attention:
The calculated type properties in the example are read-only, but you can also define readable, writeable calculated type properties, similar to the syntax of the instance calculation properties.
Gets and sets the value of the type property
Similar to an instance's property, the type property is also accessed through the point operator (.) t o carry on. H owever, type properties are obtained and set through the type itself, not through instances. Here's an example:
import Cocoa struct StudMarks { static let markCount = 97 static var totalCount = 0 var InternalMarks: Int = 0 { didSet { if InternalMarks > StudMarks.markCount { InternalMarks = StudMarks.markCount } if InternalMarks > StudMarks.totalCount { StudMarks.totalCount = InternalMarks } } } } var stud1Mark1 = StudMarks() var stud1Mark2 = StudMarks() stud1Mark1.InternalMarks = 98 print(stud1Mark1.InternalMarks) stud1Mark2.InternalMarks = 87 print(stud1Mark2.InternalMarks)
The output of the above program execution is:
97 87