iOS原理篇:关联对象

2020-03-25  本文已影响0人  绍清_shao

前言

Swift中不能再extension中为类添加存储属性,如何利用关联对象变相添加属性呢?

extension ViewController {
    struct AssociatedKeys {
        static var myTestKey: UInt8 = 0
    }
    
    // 计算属性
    var myTest: String? {
        
        get {
            guard let value = objc_getAssociatedObject(self,
                           &AssociatedKeys.myTestKey) as? String
                else { return nil }
            return value
        }
        
        set(newValue) {
            objc_setAssociatedObject(self,
                                     &AssociatedKeys.toggleState,
                                     newValue,
                                     .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        
    }
    
    
}

关联对象相关API

关联对象的底层原理

关联对象并不是存储在被关联对象本身的内存中,通过分析底层实现,它存储在由AssociationsManager管理的全局统一的一个AssociationsHashMap中,关系如下:

image

从上图可以看出,关联对象的底层实现依赖下面四个核心对象:

它们之间的关系:AssociationsHashMap里存储着某个对象的关联对象Map表,即ObjectAssociationMap,这个表存储了多个关联对象,因为在分类里可以给对象添加多个属性,也就要设置多个关联对象,ObjectAssociationMap中就是我们添加的关联对象,比如name,由ObjectionAssociation存储值和策略,当我们将关联对象(即value值,本例中是person.name = nil)设为nil时,AssociationsMap自动删除这条关联对象;当我们调用objc_removeAssociatedObjects(id object)方法时,就是移除某个对象的所有关联对象,即上图中AssociationHashMap需要移除对象的关联对象Map表;

上一篇下一篇

猜你喜欢

热点阅读