美文网首页
Swift5.1学习随笔之扩展extension添加属性

Swift5.1学习随笔之扩展extension添加属性

作者: SAW_ | 来源:发表于2020-05-19 10:53 被阅读0次
    class Person {
        var age = 0
    }
    extension Person {
        var name = "" // 报错:Extensions must not contain stored properties
    }
    

    默认情况下扩展不能包含存储属性,只能包含计算属性(本质是方法)。
    可以通过使用关联对象是实现扩展添加属性。(swift中需要导入Foundation框架)

    /*
     * object 需要关联的对象
     * key 需要传入一个地址值,将来用来取出newValue的值,外部定义一个全局变量,将全局变量的地址值传入
     * value 需要存储的值
     * policy 使用策略:
        OBJC_ASSOCIATION_ASSIGN
        OBJC_ASSOCIATION_RETAIN_NONATOMIC
        OBJC_ASSOCIATION_COPY_NONATOMIC
        OBJC_ASSOCIATION_RETAIN
        OBJC_ASSOCIATION_COPY
     */
    public func objc_setAssociatedObject(_ object: Any, _ key: UnsafeRawPointer, _ value: Any?, _ policy: objc_AssociationPolicy)
    
    /*
     * object 需要关联的对象
     * key 通过外部定义的全局变量的地址值来确定取出存储的值
     */
    public func objc_getAssociatedObject(_ object: Any, _ key: UnsafeRawPointer) -> Any?
    

    最终实现:

    var age_key = 0
    extension Person {
        var age: Int {
            get {
                objc_getAssociatedObject(self, &age_key) as! Int
            }
            set {
                objc_setAssociatedObject(self, &age_key, newValue, .OBJC_ASSOCIATION_ASSIGN)
            }
        }
    }
    
    var p = Person()
    p.age = 10
    print(p.age) // 10
    

    但是由于这个key只是需要在内部使用,在外部定义全局变量不太合理,因此需要优化,将key写在扩展内部:

    extension Person {
        //用任何类型都行,主要是那地址来用,只需要用Bool,只需要占用2个字节
        private static var AGE_KEY = false
        var age: Int {
            get {
                objc_getAssociatedObject(self, &Self.AGE_KEY) as! Int
            }
            set {
                objc_setAssociatedObject(self, &Self.AGE_KEY, newValue, .OBJC_ASSOCIATION_ASSIGN)
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Swift5.1学习随笔之扩展extension添加属性

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