Swift属性
所属分类:ios | 发布于 2023-02-13 23:25:09
之前看Swift属性文档的时候,没什么感觉,不明白属性的具体使用环境,经过这个项目的锤炼,总算有点感觉,再此来学习Swift的属性。
学习一个知识点一般都得从多个角度来分析掌握。
Swift属性可以从下面几个角度来理解:
从类型上来分,属性分为实例属性和类型属性(静态属性)。
从作用上来分,属性属性分为存储属性和计算属性。
先上一段精挑细选的代码
import Foundation
struct Todo {
// id 存储属性 声明时赋值
var id: String = UUID().uuidString
// name 存储属性 构造函数中赋值
var name: String
// point 为了演示计算属性而定义的变量
var point: Int = 110
// createdTime 存储属性 闭包表达式赋值
var createdTime: Date = {
// 闭包表达式初始化值的时候,实例的其它部分都还没有初始化。因此不能在闭包里访问其它的属性,即使它有默认值。
// 同样,调用实例方法也不行。
return Date.now
}()
// 可选存储属性
// 可选的var存储属性,如果没有赋初始值,它有一个默认的初始值nil
var dueDate: String?
// 可选的let存储属性,如果没有赋初始值,默认值为空,需要在构造函数里赋值
let priority: String?
// 计算属性
var pointParsed: Int {
get {
// 某些逻辑
if point > 100 {
return 100
} else {
return point
}
}
// 如果计算属性煤科院定义表示新值的参数名,则默认名称为newValue
set(newValue) {
self.point = newValue
}
}
// 只读计算属性
var datePickerClosedRange: ClosedRange<Date> {
Date.distantPast...Date.distantFuture
}
// 只读计算属性
var priorityText: String {
// 根本不同的priority返回不同的文本
return "priority local text"
}
// 类型属性
static var previewData: Todo = Todo.init()
init() {
// name 构造时赋值
self.name = ""
// 可选存储属性type赋值
self.priority = "important"
}
}
print(Todo.previewData)
实例属性和类型属性
实例属性
实例属性,顾名思义,就是类型实例的属性,它属于特定的实例,每创建一个实例,实例都拥有属于自己的一套属性值,实例之间的属性相互独立。
类型属性
类型属性是指为类型本身定义属性,类型属性用于定义某个类型所有实例共享的数据,无论创建了多少个该类型的实例,这些属性都只有唯一一份。类型属性相当于其它语言中的静态变量。
类型属性的语法
使用static关键字来定义类型属性。
在为类定义计算型类型属性时,可以改用关键字class来支持子类对父类的实现进行重写。
获取和设置类型属性的值
跟实例属性一样,类型属性也是通过点运算符来访问。但是类型属性是通过类型本身来访问,而不是通过实例。
存储属性和计算属性
从属性的作用的角度来说,属性分为存储属性和计算属性两种。实例属性和类型属性都可以定义存储属性和计算属性。
存储属性
一个存储属性就是存储在特定类或结构体实例里的一个变量或常量。
存储属性可以用在类和结构体中。
存储属性使用var关键字定义变量存储属性,使用let关键字定义常量存储属性。
存储属性需要分配内存空间存储属性的值。
可以在定义存储属性的时候指定默认值,也可以在构造函数中设置或修改存储属性的值,甚至修改常量存储属性的值。
通过闭包表达式来设置属性的默认值
需要在闭包中return一个值,赋给该变量
需要在闭包表达式结尾的大括号后面接一对空的小括号,表示立即执行该闭包表达式。
当使用闭包表达式来初始化属性的值时,实例的其它部分都还没初始化。这意味着不能够在闭包里访问其它的属性,就算这个属性有默认值也不行。
同样,你也不能使用隐式的self属性,或者调用其它的实例方法。
可选存储属性
可选的var属性,如果没有赋初始值,它有一个默认的初始值nil。
可选的let属性,如果没有赋初始值,默认值为空,需要在构造函数里赋值。
延迟加载存储属性
延迟加载存储属性是指当第一次调用时才会计算器初始值的属性。
在熟悉声明前使用lazy来表示一个坚持加载存储属性。
必须将延迟加载属性声明成变量(使用var关键字),因为属性的初始值可能在实例构造完成之后才会得到。而常量属性的构造 过程完成之前必须要有初始值,因此无法声明成延迟加载。
计算属性
计算属性不直接存储值,而是提供一个getter和一个可选的setter,来间接获取和设置其它属性或变量的值。
计算属性可以用在类、结构体和枚举中。
计算属性不存储值,更像是调用一个函数,返回函数的结果。
简化Setter声明
如果计算属性的setter没有定义表示新值的参数名,则可以使用默认名称newValue。
简化Getter声明
如果整个getter是单一表达式,getter会隐式地返回这个表达式结果。
只读计算属性
只有getter没有setter的计算属性叫只读计算属性。只读计算属性总返回 一个值,可以通过点运算符访问,但不能设置新的值。
属性观察器
属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,即使新值和当前值相同的时候也不例外。
添加属性观察器的位置
自定义的存储属性
继承的存储属性
继承的计算属性
对于继承的属性,可以在子类通过重写属性的方式为它添加属性观察器。对于自定义的计算属性来说,应该使用它的setter监控和响应值的变化,而不是尝试创建观察器。
属性观察器的类型
willSet在新的值被设置之前调用
didSet在新的值被设置之后调用
willSet
观察器会将新的属性值作为常量参数传入,在 willSet
的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称 newValue
表示。
同样,didSet
观察器会将旧的属性值作为参数传入,可以为该参数指定一个名称或者使用默认参数名 oldValue
。如果在 didSet
方法中再次对该属性赋值,那么新值会覆盖旧的值。
存储型属性在设置默认值或者构造器中为其赋值时,不会出发属性观察器。