The attributes of the Swift tutorial are detailed _swift

Source: Internet
Author: User
Tags truncated

A property is a value that describes a particular class, struct, or enumeration. The storage property stores the values of constants and variables as part of an instance, and calculated properties compute their values (not just storage). Computed properties exist in classes, structs, and enumerations. Storage properties are only in classes and structs.

Properties are usually associated with specific types of instances. However, properties can also be associated with the type itself, which is called a type attribute.

In addition, you can define a property observer to handle a change in the value of a property so that you can react to the user's actions. A property watcher can be added above a stored property that you define, or on a subclass property that inherits from the parent class.

1, storage properties

In the simplest case, as part of a particular class or struct instance, the storage property stores the value of a constant or variable. Storage attributes can be classified as variable storage attributes (keyword var description) and constant storage attributes (keyword let description).

When defining storage properties, you can provide a default value that is described in the "Default property value". You can also set or change the initial value of the storage property during initialization. This guideline also applies to constant storage properties (changing constant properties during initialization description)

The following example defines a structure called Fixedlengthrange that describes a range of integer values that cannot be changed when the structure is created:

Copy Code code as follows:

struct Fixedlengthrange {
var firstvalue:int
Let Length:int
}
var rangeofthreeitems = Fixedlengthrange (firstvalue:0, Length:3)
The range represents integer values 0, 1, and 2
Rangeofthreeitems.firstvalue = 6
The range now represents integer values 6, 7, and 8

An instance of Fixedlengthrange contains a variable storage property named Firstvalue and a constant storage property named length. In the above example, when the scope is determined, length is initialized and its value cannot be changed.

Storage properties for a constant structure instance
If you create a struct instance and assign it to a constant, the properties in this instance will not be changed, even if they are declared as variable attributes

Copy Code code as follows:

Let Rangeoffouritems = Fixedlengthrange (firstvalue:0, Length:4)
This range represents integer values 0, 1, 2, and 3
Rangeoffouritems.firstvalue = 6
This'll is the error, even thought Firstvalue is a variable property

Because Rangeoffouritems is a constant (let), even if firstvalue is a variable attribute, its value cannot be changed

Such an attribute is because the struct is a value type. When an instance of a value type exists as a constant, all its properties also exist as constants.

This attribute does not apply to the class because the class is a reference type. If you assign an instance of a reference type to a constant, you can still change the variable attribute of the instance.

Lazy Stored Properties (Lazy Storage property?) )

Lazy Storage property is the first time it is used when the initial value calculation. Identifies a lazy storage property by adding @lazy to the attribute declaration.

Attention

The lazy storage attribute must be declared as a variable attribute (through Var) because its initial value is not retrieved until the instance initialization completes. A constant property should be assigned before the instance initialization completes, so constant properties cannot be declared lazy storage properties.

When an attribute initializer is not able to be determined before the instance initialization completes because of external reasons, it is defined as a lazy storage property. Lazy storage attributes are useful when property initializers require complex or high cost settings and are assigned when they are needed.

The following example uses lazy storage properties to prevent unnecessary initialization operations in a class. It defines the class Dataimporter and class DataManager:

Copy Code code as follows:

Class Dataimporter {
/*dataimporter is a class to import data from a external file. The class is assumed to take a non-trivial amount of time to initialize.*/
var fileName = "Data.txt"
The Dataimporter class would provide data importing functionality here
}
Class DataManager {
@lazy var importer = Dataimporter ()
var data = string[] ()
The DataManager class would provide data management functionality here
}
Let manager = DataManager ()
Manager.data + = "Some data"
Manager.data + = "Some More Data"
The Dataimporter instance for the Importer property has not yet been

The class DataManager has a storage property called data, which is initialized to an empty string array. Although the other parts of the DataManager definition are not written, it can be seen that the purpose of DataManager is to manage string data and provide it with an access interface.

Part of the function of the DataManager class is to reference data from a file. This function is provided by the Dataimporter class, which takes a certain amount of time to initialize, because its instance needs to open the file and see the contents read into memory.

Because the DataManager instance may not require immediate management of the data referenced from the file, it is not necessary to create a new Dataimporter instance immediately when the DataManager instance is created. This allows the Dataimporter instance to be created when it is needed.

Because it is declared as the @lazy attribute, the instance of Dataimporter importer is created only when it is first accessed. For example, its FileName property needs to be accessed:

Copy Code code as follows:

println (Manager.importer.fileName)
The Dataimporter instance for the Importer property has now been created
Prints "Data.txt

Storing properties and instance variables

If you have used objective-c, you should know that it provides two ways to store values and references as part of a class instance. In addition to attributes, you can use instance variables as backing store for property values

Swift uses a single attribute declaration to unify these concepts. A swift attribute does not have an instance variable that matches it, and the backing store for the attribute is not directly accessible. This prevents the confusion of accessing values in the context of an enclosure and simplifies the declaration of attributes into a single, final statement. All information about attributes-including name, type, and memory management-is defined as part of the type definition.

2. Compute Properties

In addition to storing properties, classes, structs, and enumerations can define computed properties. The computed property does not store a value, and it provides getter and optional setters to indirectly get and set other properties and values.

Copy Code code as follows:

struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
var origin = point ()
var size = size ()
var Center:point {
get {
Let CenterX = origin.x + (SIZE.WIDTH/2)
Let CenterY = Origin.y + (SIZE.HEIGHT/2)
Return point (X:centerx, Y:centery)
}
Set (Newcenter) {
origin.x = newcenter.x-(SIZE.WIDTH/2)
ORIGIN.Y = Newcenter.y-(SIZE.HEIGHT/2)
}
}
}
var square = Rect (Origin:point (x:0.0, y:0.0), Size:size (width:10.0, height:10.0))
Let Initialsquarecenter = Square.center
Square.center = Point (x:15.0, y:15.0)
println ("Square.origin is now" (\ square.origin.x), \ (SQUARE.ORIGIN.Y))
Prints "Square.origin is now at (10.0, 10.0)"

This example defines three structures that handle geometry:

Point contains a (x,y) coordinate
Size contains width and height
Rect defines a rectangle that contains the origin and size
The RECT structure contains a computed attribute called Center. Rect the coordinates of the current center point can be obtained by origin and size properties, so you do not need to explicitly store the value of the center point. Instead, rect defines a calculated property called Center, which contains a get and a set method that manipulate the center point of the rectangle as if it were a true storage property.

The example defines a rect variable named square whose central point is initialized to (0, 0), and the height and width are initialized to 10, by the Blue Square portion of the following figure.

The center property of the variable square is accessed by the dot operator, which invokes the center getter method. Unlike the direct return of an existing value, the Getter method can be computed to return the value of the rectangle's center point. In the above example, the Getter method returns the center point (5,5).

The Center property is then set to the new value (15,15), which moves the square up to the right to the new position represented by the yellow section on the way. Set center by invoking the setter method, changing the value of coordinates x and Y in origin, and moving the square to a new position.

A brief formulation of setter statements

If the setter method of the calculated property does not define a name for the value being set, it will be replaced by the name NewValue. The following example uses a feature that defines a new version of the RECT structure:

Copy Code code as follows:

struct Alternativerect {
var origin = point ()
var size = size ()
var Center:point {
get {
Let CenterX = origin.x + (SIZE.WIDTH/2)
Let CenterY = Origin.y + (SIZE.HEIGHT/2)
Return point (X:centerx, Y:centery)
}
set {
origin.x = newvalue.x-(SIZE.WIDTH/2)
ORIGIN.Y = Newvalue.y-(SIZE.HEIGHT/2)
}
}
}

Read-only computed properties

The read-only calculation property comes with only one getter method, which can be put back to the value of the property, but not its value, by the dot operator.
Attention
You should use the var keyword to define the computed properties-including read-only computed properties-as variable properties because their values are not fixed. The Let keyword is only used by the constant attribute to indicate that the value that is set is immutable.

You can simplify the definition of a read-only calculation property by removing the Get keyword and its curly braces:

Copy Code code as follows:

struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume:double {
Return width * Height * depth
}
}
Let Fourbyfivebytwo = cuboid (width:4.0, height:5.0, depth:2.0)
println ("The volume of Fourbyfivebytwo is \ (fourbyfivebytwo.volume)")
Prints "The volume of Fourbyfivebytwo is 40.0

This example defines a three-dimensional cuboid structure cuboid, which contains three properties of the length and width, and a read-only computed property volume that represents the cuboid volume. The volume value is not set because it is calculated directly from the three properties of the height-to-width height. By providing such a read-only calculation property, Cuboid enables external users to access their current volume values.

3. Attribute Observer

The property watcher observes and responds to changes in the value of the property. When the value of a property is set, the property observer is called, even if the new value is invoked as the same as the original value.

In addition to lazy storage properties, you can add attribute observer definitions to any storage attribute. In addition, by overriding the subclass property, you can also inherit the property (store or compute) plus the attribute observer definition. Property overrides are defined in the "Overrides" section.

Attention
You do not have to define a property observer for a calculated property that is not overridden, because you can respond directly to changes in values by its setter method

When you define an observer for a property, you can use the following method individually or simultaneously:
Willset: Called before the value is set
Didset: is called immediately after setting the value

When the Willset Observer is implemented, the new property value is passed as a constant parameter. You can start a name for this parameter, and if not, this parameter is named NewValue by default.

The same is true when implementing didset observers, except that the output parameters passed represent the old attribute values.

Attention:
Willset and Didset are not invoked when the property is initialized. Is invoked only if the property value is set outside of the initialization context

The following is an example of a willset and didset usage. Defines a class stepcounter that is used to count the number of steps a person walks. It can obtain input data from pedometer or other counters, and track the number of steps in daily contact exercise.

Copy Code code as follows:

Class Stepcounter {
var totalsteps:int = 0 {
Willset (newtotalsteps) {
println ("About to set Totalsteps to \ (newtotalsteps)")
}
Didset {
If Totalsteps > OldValue {
println ("Added \ (totalsteps-oldvalue) steps")
}
}
}
}
Let Stepcounter = Stepcounter ()
Stepcounter.totalsteps = 200
About to set Totalsteps to 200
Added steps
Stepcounter.totalsteps = 360
About to set Totalsteps to 360
Added 160 Steps
Stepcounter.totalsteps = 896
About to set Totalsteps to 896
Added 536 Steps

Class Stepcounter declares a storage property totalsteps of type int, containing Willset and Didset observers. When this property is given a new value, Willset and Didset will be invoked even if the new value and the old value are the same.

The Willset observer in the example has a new name for the parameter newtotalsteps, which simply prints the value that is about to be set.

When the Totalsteps value is updated, the Didset observer is invoked, comparing the new and old values of totalsteps, and printing the increased number of steps if the new value is larger than the old value. Didset does not name the old value parameter, in this case, the default name oldvalue is used to represent the old value.

Attention

If you set the value of a property by Didset, even if the value of the property has just been set, the effect will be didset, that is, the new value is the value Didset set

4, Global and local variables

The attributes described above for calculating and observing attribute values also apply to global and local variables. Global variables are variables defined outside any function, method, closure, and type context, and local variables are variables defined in functions, methods, and closures.

The global, local variables that are encountered in the previous chapters are stored variables. As with storage properties, storage variables provide storage space for a specific type and can be accessed

However, you can define compute variables and store variable observers in global or local scope. A calculated variable does not store a value, it is used only to compute a specific value, and is defined in the same way as a computed property.

Attention
Global constants and variables are usually deferred computations, just like lazy storage properties, but do not need to add @lazy. Local constants and variables are not deferred computations.

5, type attribute

An instance property is a property of a particular type instance. When you create an instance of a type, this instance has its own set of property values, which distinguishes it from other instances.

You can also define attributes that belong to the type itself, even if you create more instances of this class, this property does not belong to any one, it belongs to the type itself, and such a property is called a type attribute.

Type attributes are useful for defining properties that are common to those instances of a particular type, such as a constant property that can be used by all instances (like a static constant in C), or a variable property (a static variable in C).

You can define storage type attributes and calculation type properties for value types (structs, enumerations). For a class, only the computed type attribute can be defined.

The storage type attribute of a value type can be a constant or a variable. A computed Type property is typically declared as a variable property, similar to a computed instance property

Attention
Do not want to store instance properties, you need to give the storage type attribute an initial value. Because the type itself cannot set a value for the storage Type property at initialization

Type attribute syntax

In C and objective-c, you define static constants, variables, and global static variables. However, in Swift, the definition of a type attribute is to be placed in a type definition, and in the curly braces of the type definition, it is shown that it is scoped in the type.

For value types, the definition Type property uses the static keyword, while the Type property that defines the class type uses the Class keyword. The following example shows the use of storing and evaluating type attributes:

Copy Code code as follows:

struct Somestructure {
static var Storedtypeproperty = "Some value."
static Var computedtypeproperty:int {
Return a Int value here
}
}
Enum Someenumeration {
static var Storedtypeproperty = "Some value." static Var computedtypeproperty:int {//return a INT value here
}
}
Class SomeClass {
class Var Computedtypeproperty:int {
Return a Int value here
}
}

Attention

The above example is for a read-only computed type attribute, but you can also define a read-writable property of a computed type like the instance property

Query and set type properties

Like instance properties, type properties are queried and set by a point operator. However, the query and settings for the type attribute are for the type, not an instance of the type. For example:

Copy Code code as follows:

println (Someclass.computedtypeproperty)
Prints "42"
println (Somestructure.storedtypeproperty)
Prints "Some value."
Somestructure.storedtypeproperty = "Another value."
println (Somestructure.storedtypeproperty)
Prints "Another value.

The following example uses two storage-type attributes in a structure to show the audio rating table for a set of sound channels. Each channel uses 0 to 10来 to represent the level of the sound.

As you can see from the chart below, two sets of sound channels are used to represent a stereo audio rating table. When the level of a channel is 0 o'clock, all the lights will not light, when the grade is 10 o'clock, all the lights will be lit. In the figure below, the left channel indicates that the sound level is 9, and the right is 7.

The above sound channels are represented by the following Audiochannel structure examples:

Copy Code code as follows:

struct Audiochannel {
static Let Thresholdlevel = 10
static var maxinputlevelforallchannels = 0
var currentlevel:int = 0 {
Didset {
If CurrentLevel > Audiochannel.thresholdlevel {
Cap the new audio level to the threshold level
CurrentLevel = Audiochannel.thresholdlevel
}
If CurrentLevel > Audiochannel.maxinputlevelforallchannels {
Store this as the new overall maximum input level
Audiochannel.maxinputlevelforallchannels = CurrentLevel
}
}
}
}

The Audiochannel structure defines two storage-type attributes. Thresholdlevel defines the highest level that audio can achieve, and for all audochannel instances, it is a constant with a value of 10. When the value of a sound signal exceeds 10 o'clock, it is truncated to its threshold of 10.

The second Type property is a variable storage property maxinputlevelforallchannels. It holds the highest level of sound accepted in all current Audiochannel instances, and it is initialized to 0.

The structure also defines a storage instance property CurrentLevel that represents the current channel sound level. This property uses the Didset property observer to detect currentlevel changes. The observer performs two checks:

If the new value of CurrentLevel is greater than the threshold Thresholdlevel, CurrentLevel will be set to Thresholdlevel
If the new value of CurrentLevel is larger than the maximum sound level that was received before all Audiochannel instances, then Maxinputlevelforallchannles will be set to cueentlevel large value.

Attention

In the first check, Didset sets a new value for CurrentLevel. This does not cause the observer to be called again.

You can create two Audiochannel instances, Leftchannel, and Rightchannel to represent a stereo system:

Copy Code code as follows:

var leftchannel = Audiochannel ()
var rightchannel = Audiochannel ()

If the currentlevel of the left channel is set to 7, its type attribute maxinputlevelforallchannels will be updated to 7:

Copy Code code as follows:

Leftchannel.currentlevel = 7
println (Leftchannel.currentlevel)
Prints "7"
println (Audiochannel.maxinputlevelforallchannels)
Prints "7"

If the currentlevel of the right channel is set to 11, its value will be truncated to 10, and the Maxinputlevelforallchannels value will also be updated to 10:
"Rightchannel.currentlevel = 11
println (Rightchannel.currentlevel)
Prints "10"
println (Audiochannel.maxinputlevelforallchannels)
Prints "10"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.