属性
属性是依赖于某个特定的类、结构体或者枚举类型的值。Swift有两种属性:存储类型和计算类型。其中存储类型可以作为实例的一部分存放变量或者常量的值,而计算类型的属性值是通过运算的来的。计算类型的属性可以在类、结构体和枚举类型中出现,但存储类型只可能出现在类和结构体类型中。
属性一般依赖于一个特定类型的实例,但是也可以依赖于类本身。依赖于类型本身的属性称为类型属性。
可以定义属性观察者来监督属性值的改变,从而作出响应。对集合不明白的看集合类型-数组详解
存储属性
常量属性let的值在初始化后不能在改变,而变量属性var的值可以随时更改。
struct FixedLengthRange {
var firstValue : Int
let length : Int
}
var rangeOfThreeItems = FixedLengthRange ( firstValue : 0 , length : 3 )
rangeOfThreeItems . firstValue = 6
结构体常量的存储属性
如果一个结构体实例被赋值给一个常量,则这个实例所拥有的存储类型的属性都不能在改变,包括变量属性在内。
let rangeOfFourItems = FixedLengthRange ( firstValue : 0 , length : 4 )
rangeOfFourItems . firstValue = 6
//编译错误,firstValue的值不能改变
延时存储属性
延时存储属性的初始值直到第一次使用的时候才进行计算,在声明时通过@lazy进行标记。
提示
一定要将延时存储属性声明为变量(var),因为它的初始值可能会在实例初始化完成后才有,而常量属性一般在实例初始化完成之前就会有值。
当属性的初始值依赖于外部银子,并且该因子的值在实例初始化完成之前不确定时,延时属性非常有用。如果属性初始化时需要进行大量的计算,也可以考虑使用延时属性。
下面是延时属性的示例:
class DataImporter {
/*
DataImporter是一个从外部文件导入数据的类。假设它需要花费较多的时间进行初始化
*/
var fileName = "data.txt"
//DataImporter类的数据导入功能
}
class DataManager {
@ lazy var importer = DataImporter ( )
var data = String [ ] ( )
//DataManager类提供数据管理功能
}
let manager = DataManager ( )
manager . data += "Some data"
manager . data += "Some more data"
//DataImporter实例还没有创建
只有问DataManager的importer属性时才会去创建这个对象。
println ( manager . importer . filename )
//创建importer属性并打印“data.txt"
存储属性与实例变量
Objective-C类的对象可以使用属性或者实例变量来存储值。Swift中并没有所谓的实例变量,而是将它们统一为属性了,这样使得属性的声明更加简化。
计算属性
除了存储属性外,类、结构体和枚举类型还可以定义计算属性。这些计算属性并不能够存储值,而是通过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 )
println ( "square.origin is now at ((square.origin.x), (square.origin.y))" )
//打印”square.origin is now at (10.0, 10.0)“
这个例子定义了三个结构体来表示几何形状:
- Point封装了(x, y)坐标。
- Size封装了宽度和高度。
- Rect用坐标原点和大小定义一个矩形。
其中Rect结构体还提供了一个center的计算属性。这个属性的值是由矩形的origin和size属性决定的,它本身并不需要存储信息。但是改变center的值,会间接的修改矩形的其它属性。