跳转至

属性

属性

目录


1.存储属性

存储属性只能用于类和结构体。一个存储属性就是存储在特定类或结构体的实例里的一个常量或变量。存储属性可以是变量存储属性,也可以是常量存储属性。

可以在定义存储属性时指定默认值,也可以在构造构成中设置或修改存储属性的值。也可以在构造过程中设置或修改存储属性的值。

定义了一个名为FixedLengthRange的结构体,它描述了一个在创建后无法修改值域宽度的区间

1
2
3
4
5
6
7
8
struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// 该区间表示整数0,1,2
rangeOfThreeItems.firstValue = 6
// 该区间现在表示整数6,7,8

1.1常量和存储属性

如果创建了一个结构体的实例并赋值给一个常量,则无法修改实例的任何属性,即使定义了变量存储属性。

1
2
3
4
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
// 该区间表示整数0,1,2,3
rangeOfFourItems.firstValue = 6
// 尽管 firstValue 是个变量属性,这里还是会报错
这种行为是由于结构体(struct)属于值类型。当值类型的实例被声明为常量的时候,它的所有属性也就成了常量。

属于引用类型的类(class)则不一样,把一个引用类型的实例赋给一个常量后,仍然可以修改实例的变量属性。

1.2延迟存储属性

延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用lazy来标示一个延迟存储属性。

延迟属性很有用,当属性的值依赖于在实例的构造过程结束前无法知道具体值的外部因素时,或者当属性的值需要复杂或大量计算时,可以只在需要的时候来计算它。

2.计算属性

计算属性可以用于类、结构体和枚举里。计算属性不直接存储值,而是提供一个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))

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)

如果计算属性的setter没有定义表示新值,则可以使用默认名称newValue。

 //中心
    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 = newCenter.x - (size.width/2)
            origin.y = newCenter.y - (size.height/2)
        }
    }

只有getter没有setter的计算属性就是**只读计算属性**。只读属性的声明可以去掉get关键字和花括号

1
2
3
4
5
    var center:Point{
        let centerX = origin.x+(size.width/2)
        let centerY = origin.y+(size.height/2)
        return Point(x:centerX,y:centerY)
    }

3.属性观察器

属性观察器监控和响应属性值的变化。每次属性被设置值的时候都会调用属性观察期,甚至新的值和现有的值相同的时候也不例外。

可以为**除了延迟属性之外的其他存储属性添加属性观察器**,也可以通过重载属性的方式为继承的属性(包括存储属性和计算属性)添加属性观察器。

可以为属性添加如下的一个或全部属性观察器。

  • willSet 在设置新的值之前调用
  • didSet 在新的值被设置之后立即调用

willSet观察器会将新的属性值作为固定参数传入,在willSet的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称newValue表示。

类似地,didSet观察器会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名oldValue。

willSet和didSet观察器在属性初始化过程中不会被调用,它们只会当属性的值在初始化之外的地方被设置时被调用。

class StepCounter{
    var totalSteps:Int = 0{
        willSet(newTotalSteps){
            println("set totalSteps to \(newTotalSteps)")
        }
        didSet{
            if totalSteps>oldValue{
                println("add \(totalSteps - oldValue) steps")

            }
        }
    }
}

let stepCounter = StepCounter()

stepCounter.totalSteps = 200

//set totalSteps to 200
//add 200 steps

4.类型属性

略

评论