swiftMac优雅使用指南Tech

Swift 中的属性

2014-08-20  本文已影响0人  乐人曹

存储属性

作为实例一部分的常量或变量。
可以提供一个默认值,或者在初始化过程中设置(或修改)属性的值,对常量的存储属性也适用。

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

存储属性变量还可以是惰性的(用 lazy 关键字表征)。
存储属性常量是不可以的,因为常量必须在初始化完成之前有值,而惰性求值可能发生在初始化完成之后。

计算属性

计算属性并不真的存储一个值。TA们提供一个 getter 和可选的 setter 间接获取和设置其他属性。

计算属性必须使用 var 关键字定义。因为计算属性的值不是固定的,会根据计算而改变。
let 关键字只用于常量属性,来表征TA们的值在实例实例化之后不会再改变)

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)
        }
    }
}

// newValue is used if a name for the new value is not set.
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)
        }
    }
}

去除 setter,计算属性就变成只读的。

struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}

属性观察器

使用 willSet didSet

可以给存储属性(惰性的除外)提供观察器,或者是任何被重写的继承而来的属性(无论是存储属性还是计算属性)。
无需给非重写的计算属性提供观察器,因为可以直接在 setter 中对值改变做出反应。

属性初始化时,观察器不会被调用。

使用 willSet,新的值(自己定义一个名字,或者默认使用newValue)会作为常量参数传递。
使用 DidSet,旧的值(自己定义一个名字,或者默认使用oldValue)会作为常量参数传递。

class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            println("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                println("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

属性与全局和局部变量

目前为止,遇到的变量(无论全局还是局部)都是存储变量,和存储属性类似。
然而,也可以定义计算变量,或者为存储变量提供观察器。

不过,要注意,全局的常量和变量总是惰性求值的(无需用 lazy 表征),而局部的常量和变量绝不会惰性求值。

类属性

为类本身定义属性,

  1. 所有实例都可以使用的常量属性(static constant in C),
  2. 所有实例都可见的变量属性(static variable in C)。

对于值类型,存储属性和计算属性都可以定义,使用 static 关键字。
对于引用类型,只可以定义计算属性,使用 class 关键字。

对于存储属性,必须为其提供默认值,毕竟,类型本身没有初始化过程...

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static let storedConstantTypeProperty = "Some value"
    static var computedTypeProperty: Int {
        // return an Int value here
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static let storedConstantTypeProperty = "Some value"
    static var computedTypeProperty: Int {
        // return an Int value here
    }
}
class SomeClass {
    class var computedTypeProperty: Int {
        // return an Int value here
    }
}
上一篇 下一篇

猜你喜欢

热点阅读