Basic introduction to Swift (15) - properties - let you know

8 tips for TED speech: Learn 18 minutes of efficient expression - key notes

Swift basic introduction (14) - class & structure (category and structure) - tell you to understand

Understanding difficulty
★★★★☆
Practical degree
★★★☆☆

Property is the value of a specific type (class, structure or enumeration), which can be used in the following ways:

Stored property: stores constants or variables in an instance, which can be used for categories and structures.
Calculated property: calculates a value within an instance, which can be used for categories, structures, and enumerations.
Type property: different from the first two, this is a property belonging to the category itself.
Property Observer: used to observe the change of property value and trigger a user-defined operation.

Storage properties

A stored property is a constant or variable stored in a specific category (category or structure). You can specify the default value when defining the storage attribute, or set or modify the value of the storage attribute during construction. The following is an example:

// Define the maximum health and mana of a game character
struct CharacterStats {
    // Specify a preset
    var hpValueMax: Double = 300
    let mpValueMax: Double
}

// Or set the value of the property at construction time
var oneStats = CharacterStats(hpValueMax: 500, mpValueMax: 120)

// After the instance is generated, you can also modify the value of the attribute
oneStats.hpValueMax = 200

// However, because mpValueMax is a constant attribute in a structure, constants cannot be modified
// The following line will report errors
oneStats.mpValueMax = 200

Storage properties of constant structures

If an instance of a structure is generated and assigned to a constant, any properties of the instance cannot be modified, even if the stored properties in the structure are variables. Examples are as follows:

// Here, the CharacterStats structure defined earlier is used
// Generate an instance of the CharacterStats structure and assign it to a constant someStats
let someStats = CharacterStats(hpValueMax: 900, mpValueMax: 150)

// This instance someStats is a constant, so even if hpValue is a variable attribute
// You still can't modify this value. This line will report an error
someStats.hpValue = 1200

As mentioned in the previous chapter, a structure belongs to a value type, so when an instance is declared as a constant, all its attributes are constants and cannot be modified.

In contrast, a class is a constant belonging to a reference type. The properties of a class instance can still be modified, because at this time, the constant stores the reference (referring to its configured location in memory space), rather than the instance.

Deferred storage properties

The delayed stored property refers to the property whose initial value is calculated only when it is called for the first time. Use lazy to represent a deferred storage attribute before the attribute declaration.

The deferred storage attribute can only be used in variables (using var keyword), because the value of the attribute may not be obtained before the instance construction is completed, and the constant attribute must have an initial value before the construction is completed.

Deferred storage properties are generally used to:

  • Delay object creation.
  • When the value of the attribute depends on other unknown classes.
class sample {
    lazy var company = member() // `var ` keyword is required
}

class member {
    var name = "Mill Swift course"
}

var firstsample = sample()
print(firstsample.company.name)

Calculation properties

In addition to storing properties, categories, structures and enumerations can also define calculated properties. Calculated properties do not directly store values, but provide a getter (using the keyword get) to access values, and an optional (optional and non mandatory) setter (using the keyword set) to indirectly set the values of other properties.

class sample {
    var no1 = 0.0, no2 = 0.0
    var length = 500.0, breadth = 100.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)

If the setter of the calculated property does not define a parameter name representing the new value, the default name newValue can be used.

// Remove the original axis parameter, and a built-in parameter name newValue will be provided
set{
            no1 = newValue.0 - (length / 2)
            no2 = newValue.1 - (breadth / 2)
        }

Read only computing properties

The setter of the calculation attribute is optional (optional and not required), so only getter s can be written according to the requirements. At this time, the calculation attribute can be simplified. The following modifications are made from the previously defined category GameCharacter:

// Define the state of a game character
class AnotherGameCharacter {
    // Initial blood volume
    var hpValue: Double = 100

    // Initial value of Defense
    var defenceValue: Double = 500

    // Total defense is only getter
    var totalDefence: Double {
        // The algorithm of total defense is defense plus 10% health
        return (defenceValue + 0.1 * hpValue)
    }

}

In the above program, since only getters are used to calculate attributes, getters can omit the keyword get and braces {}.

Note that you must use the var keyword to define calculated attributes, including read-only calculated attributes, because their values are not fixed. The let keyword is only used to declare constant attributes, which represent values that can no longer be modified after initialization.

Attribute viewer

The property observer will monitor and respond to changes in property values. Each time a property is set to a new value, it will call the property observer. The following are two property observers that can be used:

  1. willSet: before setting a new value, the new value will be passed in as a constant parameter. If the parameter name is not named, there will be a built-in parameter name newValue.
  2. didSet: call immediately after the new value is set. The old property value will be passed in as a parameter. This parameter can be named by itself or directly use the built-in parameter name oldValue.
    willSet and didSet observers are not called during property initialization
class Samplepgm {
    var counter: Int = 0{
        willSet(newTotal){
            print("Counter: \(newTotal)")
        }
        didSet{
            if counter > oldValue {
                print("New number \(counter - oldValue)")
            }
        }
    }
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

Category Properties

Type property is a property belonging to this type (class, structure or enumeration). No matter how many instances of this class are generated, there is only one type property.

Class properties are used to define the data shared by all instances generated from this class.

  • The stored Category attribute must have a default value, because the category itself does not have a constructor and cannot be set to the Category attribute during initialization.
  • The class attribute of storage type is delayed initialization. It will be initialized only when it is called for the first time, so you don't need to use lazy for it.
  • Category properties are variables or constants declared using the static keyword.

When declaring a calculated class attribute for a class, you can use the keyword class as required to support the child class to override the parent class. That is, after declaring the calculated class attribute of a Class A as a class, the class attribute can be overridden when the new class B inherits this class A.

struct Structname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
      // An Int value is returned here
   }
}

enum Enumname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
      // An Int value is returned here
   }
}

class Classname {
   class var computedTypeProperty: Int {
      // An Int value is returned here
   }
}

The computed type attribute in the example is read-only, but you can also define readable and writable computed type attributes, which is similar to the syntax of instance computed attributes.

Access or set the value of a class property

Like the instance properties, the class properties are accessed using dot syntax, but the class properties are accessed and set from the class itself, not from the instance. Examples are as follows:

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 = 96
print(stud1Mark2.InternalMarks)

Swift basic introductory knowledge learning (7) - Dictionary - tell you to understand

Efficient reading - get twice the result with half the effort - reading calligraphy - key notes - not long, all dry goods

Tags: Swift iOS xcode macOS

Posted on Mon, 06 Dec 2021 16:00:50 -0500 by jimlawrnc