[Swift]为Extension添加存储属性

众所周知, 在Swift的扩展(Extension)中只能添加计算属性, 但是有时候, 我们需要添加存储属性的话, 就用到了Runtime的方法.
在为Extension添加存储属性的时候, 主要用到了下面两个方法:

public func objc_setAssociatedObject(_ object: Any, _ key: UnsafeRawPointer, _ value: Any?, _ policy: objc_AssociationPolicy)

public func objc_getAssociatedObject(_ object: Any, _ key: UnsafeRawPointer) -> Any?

介绍

objc_setAssociatedObject 参数

存储属性

参数1( object ) : 要添加属性的类
参数2( key ): 指定存储的key, 需要使用取址运算符&(参考下面示例)
参数3( policy ): 参数属性, 是个枚举, 根据不同的数据类型选择

objc_getAssociatedObject 参数

读取属性

参数1( object ) : 要添加属性的类
参数2( key ): 指定存储的key, 需要使用取址运算符&(参考下面示例)

objc_AssociationPolicy 类型

public enum objc_AssociationPolicy : UInt {

    
    /**< Specifies a weak reference to the associated object. */
    case OBJC_ASSOCIATION_ASSIGN

    /**< Specifies a strong reference to the associated object. 
     *   The association is not made atomically. */
    case OBJC_ASSOCIATION_RETAIN_NONATOMIC

    
    /**< Specifies that the associated object is copied. 
     *   The association is not made atomically. */
    case OBJC_ASSOCIATION_COPY_NONATOMIC

    
    /**< Specifies a strong reference to the associated object.
     *   The association is made atomically. */
    case OBJC_ASSOCIATION_RETAIN

    
    /**< Specifies that the associated object is copied.
     *   The association is made atomically. */
    case OBJC_ASSOCIATION_COPY
}

示例:

以为UIView添加扩展为例

var myNameKey = 100
var myAgeKey = 101
var myOptionKey = 102

extension UIView {
    
    var myName: String {
        set {
            objc_setAssociatedObject(self, &myNameKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        
        get {
            if let rs = objc_getAssociatedObject(self, &myNameKey) as? String {
                return rs
            }
            return ""
        }
    }
    
    var myAge: Int {
        set {
            objc_setAssociatedObject(self, &myAgeKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
        }
        
        get {
            if let rs = objc_getAssociatedObject(self, &myAgeKey) as? Int {
                return rs
            }
            
            return -1
        }
    }
    
    var myOption: UILabel? {
        set {
            objc_setAssociatedObject(self, &myOptionKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        
        get {
            return objc_getAssociatedObject(self, &myOptionKey) as? UILabel
        }
    }
    
}

上面为UIView添加了三个不同类型的属性, 在使用的时候, 就可以正常的进行赋值/取值:

let view = UIView()
        
        // 赋值
        view.myAge = 100
        view.myName = "扩展的存储属性"
        view.myOption = UILabel()
        
        // 取值
        print(view.myAge)
        print(view.myName)
        print(view.myOption)

输出:

100
扩展的存储属性
Optional(>)

(完)

你可能感兴趣的:([Swift]为Extension添加存储属性)