swift 属性

属性在前面的枚举,类,结构体中都已经使用过,本章介绍属性的性质和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
 
//如果结构体的实例就是let类型,则第一次初始化后,不能再修改其任何属性的值
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// this range represents integer values 0, 1, 2, and 3
rangeOfFourItems.firstValue = 6
// 将会报错

但是类不同意结构体,因为类是指针类型,将指针类型的实例赋值给一个常量,仍然可以修改其变量成员的值。

延迟存储属性,在属性声明前部加@lazy关键字,必须是var类型的属性才能是延迟属性,延迟属性只有在用到时才会被计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class 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"
 
//在下面的语句执行以前,importer未被创建
println(manager.importer.fileName)
// 当第一次用到importer的时候,才会生成实例,打印"data.txt"

存储属性:我认为就是一般的属性,直接存储了变量或常量,可直接通过后点(.)获得或设置其值

计算属性:有get方法和set(可选)方法的属性

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
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))
//调用了center的get方法,计算了Point
let initialSquareCenter = square.center
//调用了center的set方法,origin被修改了
square.center = Point(x: 15.0, y: 15.0)
println("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// origin现在是 (10.0, 10.0)

set方法可以省略参数,省略时,默认用newValue代替,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)
    }
    }
}

只有get方法的计算属性是只读的,可以省略get,语法如下:

1
2
3
4
5
6
7
8
9
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"

属性监视器,允许开发者在设置变量值前后执行一段代码

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
class StepCounter {
    var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
        println("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
        //参数省略时,默认使用oldValue,willSet的参数也可省略,默认是newValue
        //在didSet方法里也可以修改本属性的值,并且在次数的赋值不调用willSet和didSet
        if totalSteps > oldValue  {
            println("Added \(totalSteps - oldValue) steps")
        }
    }
    }
}
let stepCounter = StepCounter()
//每设置一次totalSteps 的值,都执行willSet和didSet各一次,初始化时都不执行
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

全局变量一般都是计算延迟的,类似延迟存储变量, 但是不需要在前面加@lazy关键字

类型属性就是属于类型的属性,想C++中静态变量,只存在一份,在所有类的实例中共享。

值类型(结构体和枚举)可以定义存储变量和计算变量的类型属性,而指针类型(类)只能定义计算变量的类型属性

而存储类型属性可以是var和let型的,而计算类型属性只能是var型的

必须给存储类型属性赋初值,因为类型在初始化不能对存储类型属性赋值

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
//声明类型属性
struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
    // return an Int value here
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
    // return an Int value here
    }
}
class SomeClass {
    class var computedTypeProperty: Int {
    // return an Int value here
    }
}
//使用和赋值类型属性,使用类型调用类型属性
println(SomeClass.computedTypeProperty)
  
println(SomeStructure.storedTypeProperty)
// 打印 "Some value."
SomeStructure.storedTypeProperty = "Another value."
println(SomeStructure.storedTypeProperty)
// 打印"Another value."

 

posted @ 2015-12-22 15:39  brave-sailor  阅读(181)  评论(0编辑  收藏  举报