专注iOS开发(OC/Swift)

跟着洲洲哥一块学习Swift-属性

2016-07-25  本文已影响29人  洲洲哥

本文首发地址

Swift-属性

首先结构体和枚举都是值类型,类是引用类型。

把结构体赋值给一个变量

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}
实例化一个改对象并且读取
var rangeOfThress = FixedLengthRange(firstValue: 12, length: 100)
rangeOfThress.firstValue = 33
rangeOfThress.firstValue

rangeOfThress.length
NOTICE:rangeOfThress的实例包含一个名为firstValue的变量存储属性和一个名为length的常量存储属性。在上面的例子中,length在创建实例的时候被赋值,因为它是一个常量存储属性,所以之后无法修改它的值。

* 把结构体赋值给一个常量

let rangeItems = FixedLengthRange(firstValue: 10, length: 0)
rangeItems.firstValue
rangeItems.length
NOTICE:
常量和存储属性
 如果创建了一个结构体的实例并赋值给一个常量,则无法修改实例的任何属性,即使定义了变量存储属性:

因为rangeOfFourItems声明成了常量(用let关键字),即使firstValue是一个变量属性,也无法再修改它了。

这种行为是由于结构体(struct)属于值类型。当值类型的实例被声明为常量的时候,它的所有属性也就成了常量。

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

存储属性和实例变量

如果您有过 Objective-C 经验,应该知道有两种方式在类实例存储值和引用。对于属性来说,也可以使用实例变量作为属性值的后端存储。

Swift 编程语言中把这些理论统一用属性来实现。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 * 0.5
            let centerY = origin.y + size.height * 0.5
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            origin.x = newCenter.x - size.width * 0.5
            origin.y = newCenter.y - size.height * 0.5
        }
    }
}
var squre = Rect(origin: Point(x: 0.0,y: 0.0), size: Size(width: 10, height: 10))
let initialsqureCenter = squre.center
squre.center = Point(x: 100, y: 100)


squre.origin.x // 95
squre.size.width // 10
squre.center.x // 100

只读计算属性

只有 getter 没有 setter 的计算属性就是只读计算属性。只读计算属性总是返回一个值,可以通过点运算符访问,但不能设置新的值。

NOTICE:必须使用var关键字定义计算属性,包括只读计算属性,因为他们的值不是固定的。let关键字只用来声明常量属性,表示初始化后再也无法修改的值。
只读计算属性的声明可以去掉get关键字和花括号:

struct Cuboid {
    var width = 0.0,heigt = 0.0,depth = 0.0
    var volume: Double {
        return heigt * width * depth
    }
}

let fourbyFr = Cuboid(width: 1, heigt: 2, depth: 3)
fourbyFr.volume

属性监视器

属性监视器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性监视器,甚至新的值和现在的值相同的时候也不例外。
可以为除了延迟存储属性之外的其他存储属性添加属性监视器,也可以通过重载属性的方式为继承的属性(包括存储属性和计算属性)添加属性监视器。属性重载请参考继承一章的重载。
注意:不需要为无法重载的计算属性添加属性监视器,因为可以通过 setter 直接监控和响应值的变化。

可以为属性添加如下的一个或全部监视器:

willSet在设置新的值之前调用
didSet在新的值被设置之后立即调用
willSet监视器会将新的属性值作为固定参数传入,在willSet的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称newValue表示。

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

注意:willSet和didSet监视器在属性初始化过程中不会被调用,他们只会当属性的值在初始化之外的地方被设置时被调用。

这里是一个willSet和didSet的实际例子,其中定义了一个名为StepCounter的类,用来统计当人步行时的总步数,可以跟计步器或其他日常锻炼的统计装置的输入数据配合使用。

NOTICE:
默认的会在willSet的时候吧”newValue“作为参数传入,自己定义一个参数即可代替newValue
默认的会在didSet的时候吧”oldValue“作为参数传入,自己定义一个参数即可代替oldValue

class StepCounter {
    var totalSteps: Int = 0 {
        willSet {
         print("About to set totalSteps to \(newValue)")
        }
        didSet(oldToalValue) {
            if totalSteps > oldToalValue {
                 print("Added \(totalSteps - oldToalValue) steps")
            }
        }
    }
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 100

stepCounter.totalSteps = 200

如有问题可添加我的QQ:1290925041
还可添加QQ群:234812704(洲洲哥学院)
欢迎各位一块学习,提高逼格!
也可以添加洲洲哥的微信公众号

更多消息

更多信iOS开发信息 请以关注洲洲哥 的微信公众号,不定期有干货推送:

这里写图片描述
上一篇下一篇

猜你喜欢

热点阅读