跟着洲洲哥一块学习Swift-属性
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开发信息 请以关注洲洲哥 的微信公众号,不定期有干货推送:
这里写图片描述