iOS开发笔记iOS 日记本

Swift 属性

2021-05-29  本文已影响0人  long弟弟

You can't connect the dots looking forward; you can only connect them looking backwards.
-- Steve Jobs

说一下Swift的属性。

??,这有什么好说的?.jpeg

很久没有跟人聊概念技术尤其是耳熟能详的概念,仔细一想,这属性到底是啥?

我知道你问的是啥,我也知道是啥,但我不知道你想让我说啥,尴尬了。

属性:是描述一个事物的特征?我都怀疑我还是不是不爱说话的程序员了...

比方说抽象一个Person类,定义一个Int的age就是属性。

class Person {
    var age: Int
}

struct Point {
    var x: Int
    var y: Int
}

在Swift中,通过实例访问的属性称为实例属性,通过类名访问的属性称为类型属性

实例属性分存储属性计算属性。存储属性类似成员变量存储在实例的内存中;计算属性本质是方法不占用实例的内存。

存储属性

存储属性规定:在创建类、结构体的实例时,必须为所有的存储属性设置一个合适的初始值。使用lazy可以定义一个延迟存储属性,在第一次用到属性的时候才会进行初始化。

lazy属性必须是var,多线程访问不能保证只初始化一次。结构体实例需要定义为var,因为延迟属性初始化时需改变结构体内存。

计算属性

定义计算属性只能是var,不能用let。
set传入的新值默认是newValue,也可以自定义。
只有get,没有set就是只读计算属性。

类型属性也分存储类型属性计算类型属性。存储类型属性相当于全局变量,整个程序运行过程中只有一份内存,用static修饰;计算类型属性相当于全局函数。用static/class修饰。static修饰的不能被子类重写,class修饰的可以重写。

存储类型属性

默认lazy且线程安全(调用dispatch_once_f),第一次使用时才初始化

计算类型属性

默认lazy且线程安全

class Person {
    var gender: String //存储属性
    //计算属性 
    //根据gender是男是女算出sex值,方便传给后台Bool值,设置sex时同时改变gender的值
    var sex: Bool { 
        set {
            gender =  newValue ? "男" : "女"
        }
        get {
            gender == "男"
        }
    }
    //存储类型属性
    static var count: Int = 0
    //计算存储类型
    static var hands: Int {
        get {
            count * 2
        }
    }
    //懒加载存储属性,延迟加载
    lazy var pet = Pet()
    var cloth = Cloth()
    
    init(gender: String) {
        self.gender = gender
    }
}

class Pet {
    var name: String = "旺财"
    init() {
        //用到的时候初始化
        print("Pet init")
    }
}

class Cloth {
    init() {
        print("Cloth init")
    }
}

属性观察器

为非lazy的var存储属性社会属性观察器,初始化器中设置属性值(设置初始值)不会触发属性观察器

var age: Int {
        willSet {
            print("willset", newValue)
        }
        didSet {
            print("didset", oldValue, radius)
        }
    }

重写属性

存储属性、计算属性重写为计算属性,只能重写var属性,子类重写后的属性的权限不能小于父类的。被final修饰的属性禁止被重写。

可以在子类中为父类属性增加属性观察器(只读、let除外)
存储属性没有属性观察器的增加属性观察器,有属性观察器的调用顺序子类的willSet->父willSet->父didSet->子类的didSet

计算属性先要获取oldValue,所以顺序是get->sub willSet->set->get->sub didSet

class Person {
    class var age: Int {
        set {
            print("set", newValue)
        }
        get {
            print("get")
            return 18
        }
    }
}

class Student: Person {
    override static var age: Int {
        willSet {
            print("Sub willset", newValue)
        }
        didSet {
            print("Subdidset", oldValue, age)
        }
    }
}

var s = Student()
Student.age = 19
/*
get
Sub willset 19
set 19
get
Subdidset 18 18
*/
上一篇下一篇

猜你喜欢

热点阅读