可以不改变源码的情况下增加实例变量。
可与分类配合使用,为分类增加属性。(类别是不能添加成员变量的(property本质也是成员变量 = var + setter、getter),原因是因为一个类的内存大小是固定的,一个雷在load方法执行前就已经加载在内存之中,大小已固定)
AssociationsManager
class AssociationsManager {
static OSSpinLock _lock;
static AssociationsHashMap *_map; // associative references: object pointer -> PtrPtrHashMap.
public:
AssociationsManager() { OSSpinLockLock(&_lock); }
~AssociationsManager() { OSSpinLockUnlock(&_lock); }
AssociationsHashMap &associations() {
if (_map == NULL)
_map = new AssociationsHashMap();
return *_map;
}
};
AssociationsManager里面是由一个静态AssociationsHashMap来存储所有的关联对象的。这相当于把所有对象的关联对象都存在一个全局map里面。而map的的key是这个对象的指针地址(任意两个不同对象的指针地址一定是不同的),而这个map的value又是另外一个AssociationsHashMap,里面保存了关联对象的kv对。
销毁
在obj dealloc时候会调用object_dispose,检查有无关联对象,有的话_object_remove_assocations删除
id
object_dispose(id obj)
{
if (!obj) return nil;
// 销毁对象
objc_destructInstance(obj);
// 释放内存
free(obj);
return nil;
}
void *objc_destructInstance(id obj)
{
if (obj) {
// Read all of the flags at once for performance.
bool cxx = obj->hasCxxDtor();
bool assoc = obj->hasAssociatedObjects();
// This order is important.
// C++ 析构
if (cxx) object_cxxDestruct(obj);
// 移除 Associated Object
if (assoc) _object_remove_assocations(obj);
// ARC 下调用实例变量的 release 方法,移除 weak 引用
obj->clearDeallocating();
}
return obj;
}