Swift语法 -- [08 - 属性]

1. 存储属性&计算属性

Swift中跟实例对象相关的属性可以分为2大类

存储属性(Stored Property)

  • 类似于成员变量这个概念
  • 存储在实例对象的内存中
  • 结构体、类可以定义存储属性
  • 枚举不可以定义存储属性

计算属性(Computed Property)

  • 本质就是方法(函数)
  • 不占用实例对象的内存
  • 枚举、结构体、类都可以定义计算属性
struct Circle {
    // 存储属性
    var radius: Double
    // 计算属性
    var diameter: Double {
        set {
            radius = newValue / 2
        }
        get {
            return radius * 2
        }
    }
}

2. 计算属性

set传入的新值默认叫做newValue,也可以自定义

 struct Circle {
    var radius: Double
    var diameter: Double {
        set(newDiameter) {
            radius = newDiameter / 2
        } 
        get {
            radius * 2 }
        } 
}

只读计算属性:只有get,没有set

struct Circle {
    var radius: Double
    var diameter: Double {
        get {
            radius * 2
        } 
    }
}

  • 定义计算属性只能用var,不能用let
    • let代表常量:值是一成不变的
    • 计算属性的值是可能发生变化的(即使是只读计算属性)

3. 枚举rawValue原理

枚举原始值rawValue的本质是:只读计算属性

 enum TestEnum : Int {
    case test1 = 1, test2 = 2, test3 = 3
    var rawValue: Int {
        switch self {
        case .test1:
            return 10
        case .test2:
            return 11
        case .test3:
            return 12 }
    } 
}

4. 延迟存储属性(Lazy Stored Property)

使用lazy可以定义一个延迟存储属性,在第一次用到属性的时候才会进行初始化

  • lazy属性必须是var,不能是let
    • let必须在实例对象的初始化方法完成之前就拥有值
  • 如果多条线程同时第一次访问lazy属性
    • 无法保证属性只被初始化1次
class PhotoView {
    lazy var image: Image = {
        let url = "https://www.../xx.png"        
        let data = Data(url: url)
        return Image(data: data)
    }() 
} 

5. 属性观察器(Property Observer)

可以为非lazy的var存储属性设置属性观察器

struct Circle {
    var radius: Double {
        willSet {
            print("willSet", newValue)
       } 
       didSet {
            print("didSet", oldValue, radius)
        }
   } 
  init() {
        self.radius = 1.0
        print("Circle init!")
    }
}

  • willSet会传递新值,默认叫newValue
    • didSet会传递旧值,默认叫oldValue
    • 在初始化器中设置属性值不会触发willSet和didSet

6.类型属性(Type Property)

严格来说,属性可以分为

实例属性(Instance Property): 只能通过实例对象去访问

  • 存储实例属性(Stored Instance Property):存储在实例对象的内存中,每个实例对象都有1份
  • 计算实例属性(Computed Instance Property)

类型属性(Type Property):只能通过类型去访问

  • 存储类型属性(Stored Type Property):整个程序运行过程中,就只有1份内存(类似于全局变量)
  • 计算类型属性(Computed Type Property)

可以通过static定义类型属性 p如果是类,也可以用关键字class

struct Car {
    static var count: Int = 0
    init() {
        Car.count += 1
    }
}

不同于存储实例属性,你必须给存储类型属性设定初始值

  • 因为类型没有像实例对象那样的init初始化器来初始化存储属性

存储类型属性默认就是lazy,会在第一次使用的时候才初始化

  • 就算被多个线程同时访问,保证只会初始化一次
  • 存储类型属性可以是let

枚举类型也可以定义类型属性(存储类型属性、计算类型属性)

7. 单例模式

通过 类型属性+let+private 来写单例;

 public class FileManager {
    public static let shared = {
        // ....
        // ....
        return FileManager()
     }()
    private init() { }
}

你可能感兴趣的:(Swift语法 -- [08 - 属性])