###存储属性
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// 该区间表示整数0,1,2
rangeOfThreeItems.firstValue = 6
// 该区间现在表示整数6,7,8
-
常量和存储属性
如果创建了一个结构体的实例并赋值给一个常量,那么就无法修改实例的任何属性,即使定义了变量存储属性
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4) // 该区间表示整数0,1,2,3 rangeOfFourItems.firstValue = 6 // 尽管 firstValue 是个变量属性,这里还是会报错
-
延迟存储属性
延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用 @lazy 来标示一个延迟存储属性。
class DataImporter { /* DataImporter 是一个将外部文件中的数据导入的类。 这个类的初始化会消耗不少时间。 */ var fileName = "data.txt" // 这是提供数据导入功能 } class DataManager { @lazy var importer = DataImporter() var data = String[]() // 这是提供数据管理功能 } let manager = DataManager() manager.data += "Some data" manager.data += "Some more data" // DataImporter 实例的 importer 属性还没有被创建
###计算属性
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 at (\(square.origin.x), \(square.origin.y))")
// 输出 "square.origin is now at (10.0, 10.0)”
-
便捷 setter 声明
如果计算属性的 setter 没有定义表示新值的参数名,则可以使用默认名称 newValue。
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) } } }
-
只读计算属性
只有 getter 没有 setter 的计算属性就是只读计算属性,只读计算属性的声明恩可以去掉 get 关键字和话括号:
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)") // 输出 "the volume of fourByFiveByTwo is 40.0"
###属性监视器
可以为属性添加如下的一个或全部监视器:
- willSet 在设置新的值之前调用,会将新的属性值作为固定参数传入,默认名为 newValue
- didSet 在新的值被设置之后立即调用,会将旧的属性值作为参数传入,默认名为 oldValue
willSet 和 didSet 监视器在属性初始化过程中不会被调用,他们只会当属性的值在初始化之外的地方被设置时被调用
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
println("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
println("Added \(totalSteps - oldValue) steps")
}
}
}
}
###类型属性
类型属性用于定义特定类型所有实例所共享的数据。
-
类型属性语法
使用关键字 static 来定义值类型的类型属性,关键字 class 来为类定义类型属性
struct SomeStructure { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { // 这里返回一个 Int 值 } } enum SomeEnumeration { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { // 这里返回一个 Int 值 } } class SomeClass { class var computedTypeProperty: Int { // 这里返回一个 Int 值 } }
-
示例
struct AudioChannel { static let thresholdLevel = 10 static var maxInputLevelForAllChannels = 0 var currentLevel: Int = 0 { didSet { if currentLevel > AudioChannel.thresholdLevel { // 将新电平值设置为阀值 currentLevel = AudioChannel.thresholdLevel } if currentLevel > AudioChannel.maxInputLevelForAllChannels { // 存储当前电平值作为新的最大输入电平 AudioChannel.maxInputLevelForAllChannels = currentLevel } } } } var leftChannel = AudioChannel() var rightChannel = AudioChannel() leftChannel.currentLevel = 7 println(leftChannel.currentLevel) // 输出 "7" println(AudioChannel.maxInputLevelForAllChannels) // 输出 "7" rightChannel.currentLevel = 11 println(rightChannel.currentLevel) // 输出 "10" println(AudioChannel.maxInputLevelForAllChannels) // 输出 "10"
END