能否为分类添加 “成员变量” ?
// 添加关联对象
id objc_getAssociateObject(id object, const void * key)
/* objc_Association 关联策略 */
id objc_setAssociateObject(id object, const void * key, id value , objc_Association )
//移除关联对象
id objc_removeAssociatedObject(id object)
为分类所添加的成员变量添加在哪里?
所有对象的关联内容都在同一个全局容器内
关联对象的本质
setobjc_association(处理 Key) ->
objectAssociationMap (#selector -作为 key) - >
AssociationHashMap(全局容器 -key value 关联 和对象指针 ) ->
流程图:

源码分析:
id
objc_getAssociatedObject(id object, const void *key)
{
return objc_getAssociatedObject_non_gc(object, key);
}
void
objc_setAssociatedObject(id object, const void *key, id value,
objc_AssociationPolicy policy)
{
objc_setAssociatedObject_non_gc(object, key, value, policy);
}
#endif
void objc_removeAssociatedObjects(id object)
{
#if SUPPORT_GC
if (UseGC) {
auto_zone_erase_associative_refs(gc_zone, object);
} else
#endif
{
if (object && object->hasAssociatedObjects()) {
_object_remove_assocations(object);
}
}
}
void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy) {
// retain the new value (if any) outside the lock.
ObjcAssociation old_association(0, nil);
id new_value = value ? acquireValue(value, policy) : nil;
{
// 关联对象对象管理类 c++实现 全局容器
AssociationsManager manager;
AssociationsHashMap &associations(manager.associations());
disguised_ptr_t disguised_object = DISGUISE(object);
if (new_value) {
// break any existing association.
AssociationsHashMap::iterator i = associations.find(disguised_object);
if (i != associations.end()) {
// secondary table exists
ObjectAssociationMap *refs = i->second;
ObjectAssociationMap::iterator j = refs->find(key);
if (j != refs->end()) {
old_association = j->second;
j->second = ObjcAssociation(policy, new_value);
} else {
(*refs)[key] = ObjcAssociation(policy, new_value);
}
} else {
// create the new association (first time).
ObjectAssociationMap *refs = new ObjectAssociationMap;
associations[disguised_object] = refs;
(*refs)[key] = ObjcAssociation(policy, new_value);
object->setHasAssociatedObjects();
}
} else {
// setting the association to nil breaks the association.
AssociationsHashMap::iterator i = associations.find(disguised_object);
if (i != associations.end()) {
ObjectAssociationMap *refs = i->second;
ObjectAssociationMap::iterator j = refs->find(key);
if (j != refs->end()) {
old_association = j->second;
refs->erase(j);
}
}
}
}
// release the old value (outside of the lock).
if (old_association.hasValue()) ReleaseValue()(old_association);
}
转换成类似JSON

网友评论