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 方法中再次对该属性赋值,那么新值会覆盖旧的值。

存储型属性在设置默认值或者构造器中为其赋值时,不会出发属性观察器。

文哥博客(https://wenge365.com)属于文野个人博客,欢迎浏览使用

联系方式:qq:52292959 邮箱:52292959@qq.com

备案号:粤ICP备18108585号 友情链接