前言
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
中,关系如下:
从上图可以看出,关联对象的底层实现依赖下面四个核心对象:
AssociationsManager
AssociationsHashMap
ObjectAssociationMap
ObjectionAssociation
它们之间的关系:AssociationsHashMap
里存储着某个对象的关联对象Map
表,即ObjectAssociationMap
,这个表存储了多个关联对象,因为在分类里可以给对象添加多个属性,也就要设置多个关联对象,ObjectAssociationMap
中就是我们添加的关联对象,比如name
,由ObjectionAssociation
存储值和策略,当我们将关联对象(即value
值,本例中是person.name = nil
)设为nil
时,AssociationsMap
自动删除这条关联对象;当我们调用objc_removeAssociatedObjects(id object)
方法时,就是移除某个对象的所有关联对象,即上图中AssociationHashMap
需要移除对象的关联对象Map
表;
网友评论