Swift 属性

作者: long弟弟 | 来源:发表于2021-05-29 00:00 被阅读0次

    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
    */
    

    相关文章

      网友评论

        本文标题:Swift 属性

        本文链接:https://www.haomeiwen.com/subject/tkzmjltx.html