计算属性由类,结构和枚举提供。 存储属性仅由类和结构提供。
Stored 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
Stored Properties of Constant Structure Instances 常量结构实例的存储属性
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 因为rangeOfFourItems这是一个常量 , 它的属性值无法改变
Lazy Stored Properties 延迟存储属性
Note:您必须始终将lazy属性声明为变量(使用var关键字),因为它的初始值可能无法在实例初始化完成后检索。 常量属性在初始化完成之前必须始终具有值,因此不能声明为延迟。
class DataImporter{
/* DataImporter is a class to import data from an external file. The class is assumed to take a non-trivial 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
}
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
print(manager.importer.fileName) // 现在才实例化类里面的延迟属性
// the DataImporter instance for the importer property has now been created
// Prints "data.txt"
Note:如果标记有lazy修饰符的属性由多个线程同时访问,并且该属性尚未初始化,则不能保证该属性只被初始化一次。
Computed Properties 计算属性
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现在是(5,5)square.origin是(0,0)square.size = (10.0,10.0) square.center是通过计算属性的getter方法计算出来的
square.center=Point(x:15.0,y:15.0) // square.center现在是(15,15)square.origin是(10,10)square.size = (10.0,10.0) square.origin是通过计算属性的setter方法计算出来的
print("square.origin is now at (\(square.origin.x),\(square.origin.y))")
// Prints "square.origin is now at (10.0, 10.0)"
Read-Only Computed Properties 只读计算属性 那就把setter方法去掉
Property Observers 属性观察器
willSet is called just before the value is stored.
didSet is called immediately after the new value is stored.
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
Global and Local Variables 全局和局部变量
Type Properties 类属性
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 var overrideableComputedTypeProperty:Int{
return107
}
}
访问 和 设置 类属性
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"
struct AudioChannel{
static let thresholdLevel=10
static var maxInputLevelForAllChannels=0
var currentLevel:Int=0{
didSet{
if currentLevel>AudioChannel.thresholdLevel { // 在本类里面调用类属性
// cap the new audio level to the threshold level
currentLevel=AudioChannel.thresholdLevel
}
if currentLevel>AudioChannel.maxInputLevelForAllChannels {
// store this as the new overall maximum input level
AudioChannel.maxInputLevelForAllChannels=currentLevel
}
}
}
}
var leftChannel=AudioChannel()
var rightChannel=AudioChannel()
leftChannel.currentLevel=7
print(leftChannel.currentLevel) // Prints "7"
print(AudioChannel.maxInputLevelForAllChannels) // Prints "7"
rightChannel.currentLevel=11
print(rightChannel.currentLevel) // Prints "10"
print(AudioChannel.maxInputLevelForAllChannels) // Prints "10"