PART_A 属性简介
PART_B 存储属性
案例
struct Range { var startIndex: Int // 变量存储属性 let width: Int // 常量存储属性(创建实例时被初始化) } var range = Range(startIndex: 0,width: 5) // 区间为 0...5 range.startIndex = 3 // 区间为 3...8
常量结构体的存储属性
延迟存储属性:
lazy var
声明. 第一次被调用时才计算其属性的初始化值使用场景
当被
lazy
标记的属性在没有初始化时就同时被多个线程访问,则无法保证该属性只会被初始化一次class DataProvider { // 导入文件(耗时操作) var fileName = "data.txt" } class DataManager { lazy var provider = DataProvider() // 数据管理 var data = [String]() } let manager = DataManager() manager.data.append("Some data") manager.data.append("Some more data") // DataProvider 实例还没有被创建 print(manager.importer.fileName) // DataProvider 实例被创建(此时第一次被调用)
存储属性和实例变量
PART_C 计算属性(-案例值得琢磨-)
不直接存储值,提供
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 { // getter:返回 Point 实例(中心) get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX,y: centerY) } // setter:设置 Point 中心坐标 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 squareCenter = square.center // 中心坐标 (5,5) square.center = Point(x: 15.0,y: 15.0) print("square.origin is now at (\(square.origin.x),\(square.origin.y))") // 输出 "square.origin is now at (10.0,10.0)”
便捷
setter
声明只读计算属性:只有
getter
没有setter
的计算属性,总是返回一个值struct Cuboid { var width = 0.0,height = 0.0,depth = 0.0 // 只读计算属性 var volume: Double { return width * height * depth } } let rect1 = Cuboid(width: 4.0,height: 5.0,depth: 2.0) print("the volume of rect1 is \(rect1.volume)")
PART_D 属性观察器
-
willSet
:新值被设置前调用didSet
:新值被设置后调用class StepCounter { var totalSetps: Int = 0 { // newTotalSteps:新值(默认 newValue) willSet(newTotalSteps) { print(newTotalSteps) } didSet { // oldValue:旧值 if totalSetps > oldValue { print(totalSetps - oldValue) } } } } let stepCounter = StepCounter() stepCounter.totalSetps = 50 // 50 // 50 stepCounter.totalSetps = 90 // 90 // 40 stepCounter.totalSetps = 80 // 80
若一个属性的
didSet
观察器里赋值,该值会替代之前设置的值
PATR_E 全局变量和局部变量
定义
注意
全局的常量或变量都是延迟计算的(省略
lazy
修饰符)局部的常量或变量从不延迟计算
PART_F 类型属性(static
):定义某个类型所有实例共享的数据
语法
struct SomeStructure { // 存储型类型属性 static var storedTypeProperty = "Some value." // 计算型类型属性(本例所用是只读的) static var computedTypeProperty: Int { return 5 } } 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 7 } // 为类定义计算型类型属性时,改用 class 支持子类对父类的实现进行重写 class var overrideableComputedTypeProperty: Int { return 8 } }
案例:两个喇叭的音量
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 // 左声道音量为 7 rightChannel.currentLevel = 11 // 右声道音量为 10(控制在音量上限内)
以上。如有错误和疑问,欢迎指正提出。 catface.wyh@gmail.com