您的位置:首页 > 移动开发 > Swift

Swift研究之编程高级教程(二)属性,存储属性详解

2014-08-06 13:36 399 查看


属性

属性是依赖于某个特定的类、结构体或者枚举类型的值。Swift有两种属性:存储类型和计算类型。其中存储类型可以作为实例的一部分存放变量或者常量的值,而计算类型的属性值是通过运算的来的。计算类型的属性可以在类、结构体和枚举类型中出现,但存储类型只可能出现在类和结构体类型中。

属性一般依赖于一个特定类型的实例,但是也可以依赖于类本身。依赖于类型本身的属性称为类型属性。

可以定义属性观察者来监督属性值的改变,从而作出响应。对集合不明白的看集合类型-数组详解


存储属性

常量属性let的值在初始化后不能在改变,而变量属性var的值可以随时更改。

1
2
3
4
5
6
7

struct FixedLengthRange {

    var firstValue: Int
    let length: Int

}
 

var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6

结构体常量的存储属性

如果一个结构体实例被赋值给一个常量,则这个实例所拥有的存储类型的属性都不能在改变,包括变量属性在内。

1
2
3

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)

rangeOfFourItems.firstValue = 6
//编译错误,firstValue的值不能改变

延时存储属性

延时存储属性的初始值直到第一次使用的时候才进行计算,在声明时通过@lazy进行标记。

提示

一定要将延时存储属性声明为变量(var),因为它的初始值可能会在实例初始化完成后才有,而常量属性一般在实例初始化完成之前就会有值。

当属性的初始值依赖于外部银子,并且该因子的值在实例初始化完成之前不确定时,延时属性非常有用。如果属性初始化时需要进行大量的计算,也可以考虑使用延时属性。

下面是延时属性的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

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属性时才会去创建这个对象。

1
2

println(manager.importer.filename)

//创建importer属性并打印“data.txt"

存储属性与实例变量

Objective-C类的对象可以使用属性或者实例变量来存储值。Swift中并没有所谓的实例变量,而是将它们统一为属性了,这样使得属性的声明更加简化。


计算属性

除了存储属性外,类、结构体和枚举类型还可以定义计算属性。这些计算属性并不能够存储值,而是通过getter方法和可选的setter方法来间接的获取和设置其它属性和值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

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的值,会间接的修改矩形的其它属性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: