swift4.03 学习笔记(11)

Properties(属性)

属性存储
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

结构体FixedLengthRange存储了一个变量属性firstValue和常量属性。

常量属性和变量属性都可以在初始化是设置初始值,但是常量属性在初始化后就不能修改了。

常量属性存储结构体实例
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6
// this will report an error, even though firstValue is a variable property

结构体实例赋值给常量属性后,结构体的变量属性也不能修改。

这是因为,结构体是值类型。而引用类型的类,赋值给常量属性后是可以类的修改变量属性的。

Lazy 属性

lazy属性在初始化时,不执行。在第一次使用时,才执行。

  • lazy属性必须是变量,不能是常量。
class DataImporter {
    /*
     DataImporter is a class to import data from an external file.
     The class is assumed to take a nontrivial 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
}

DataManager的属性data的数据来源方式有两种,一种是通过外部添加:

let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
// the DataImporter instance for the importer property has not yet been created

另一种是通过DataImporter导入,而DataImporter导入需要加载文件,因此把属性importer设置为lazy,在初始化时不加载文件,只有在第一次调用importer时,才开始加载文件:

print(manager.importer.filename)
// the DataImporter instance for the importer property has now been created
// Prints "data.txt"

计算属性

类,结构体,枚举除了储存属性外,你也可以定义计算属性(类似Java中的getter,setter方法)

  • 计算属性必须是变量,不能是常量。常量的值初始化后就不能变了,而计算属性的值是根据其他的值变动的。
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)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// Prints "square.origin is now at (10.0, 10.0) "
简写setter声明
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)
        }
    }
}

Swift默认为setter提供newValue参数名。

只读的计算属性
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)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// Prints "the volume of fourByFiveByTwo is 40.0"

声明只读计算属性可以省略掉get

属性的监听

willSet和didSet,可以对除了lazy属性以外的任何属性使用:

  • willSet存储值之前调用
  • didSet值存储之后调用
class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 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

使用willSet 和 didSet对父类监听时,父类初始化完成后才能监听到

全局变量和本地变量

  • 全局变量定义在方法,函数,闭包和类型之外
  • 本地变量定义在方法,函数,闭包之内。

全局变量和本地变量都可以定义成计算属性,也可以使用willSet,didSet监听。

Type Properties(类型属性)

不需要实例化就可以访问的属性,类似Java的类中的静态属性。

类型属性的语法

使用static关键字在结构体,类,枚举中定义静态属性。

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6
    }
}
class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
   
}

如果希望类的子类可以重写类型属性可以使用class

class SomeClass {
  
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}
获取和设置类型属性

直接使用类名.属性名 获取或者设置

print(SomeStructure.storedTypeProperty)
// Prints "Some value."
SomeStructure.storedTypeProperty = "Another value."
print(SomeStructure.storedTypeProperty)
// Prints "Another value."
print(SomeEnumeration.computedTypeProperty)
// Prints "6"
print(SomeClass.computedTypeProperty)
// Prints "27"

你可能感兴趣的:(swift4.03 学习笔记(11))