0x002 runtime Associate方法关联的对象,是否需要在dealloc中释放?

runtime Associate方法关联的对象,是否需要在dealloc中释放?

1、创建LGPerson的分类LGPerson+LG

LGPerson+LG.h

@interface LGPerson (LG)

@property (nonatomic, copy) NSString *lgProperty;

@end

LGPerson+LG.m

#import 

const char *kLGProperty = "LGPerson+LGProperty";

@implementation LGPerson (LG)

- (void)setLgProperty:(NSString *)lgProperty {
    objc_setAssociatedObject(self, kLGProperty, lgProperty, OBJC_ASSOCIATION_COPY);
}

- (NSString *)lgProperty {
    return objc_getAssociatedObject(self, kLGProperty);
}

@end

2、分析

1)objc_setAssociatedObject(self, kLGProperty, lgProperty, OBJC_ASSOCIATION_COPY)

这个方法会在全局关联对象哈希表T中查找或新建一张对象关联哈希表To,在T中以对象selfkeyTovalue
To中以kLGPropertykeylgPropertyvalue

2)objc_getAssociatedObject(self, kLGProperty)

这里跟上面一样的逻辑,在二重哈希表中查找对应的值返回。

3、案例代码

void test6() {
    LGPerson *person = [[LGPerson alloc] init];
    person.lgProperty = @"测试";
    NSLog(@"%@", person);
}

1)当上面方法执行结束后,会调用objc_release(id obj)方法

__attribute__((aligned(16), flatten, noinline))
void 
objc_release(id obj)
{
    if (!obj) return;
    if (obj->isTaggedPointer()) return;
    return obj->release();
}

2)接着是release方法

inline void
objc_object::release()
{
    ASSERT(!isTaggedPointer());

    if (fastpath(!ISA()->hasCustomRR())) {
        rootRelease();
        return;
    }

    ((void(*)(objc_object *, SEL))objc_msgSend)(this, @selector(release));
}

3)接着是rootRelease方法,object_dispose方法

id 
object_dispose(id obj)
{
    if (!obj) return nil;

    objc_destructInstance(obj);    
    free(obj);

    return nil;
}

4)接着是objc_destructInstance方法

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.
        if (cxx) object_cxxDestruct(obj);
        if (assoc) _object_remove_assocations(obj);
        obj->clearDeallocating();
    }

    return obj;
}

5)最后是_object_remove_assocations方法

void
_object_remove_assocations(id object)
{
    ObjectAssociationMap refs{};

    {
        AssociationsManager manager;
        AssociationsHashMap &associations(manager.get());
        AssociationsHashMap::iterator i = associations.find((objc_object *)object);
        if (i != associations.end()) {
            refs.swap(i->second);
            associations.erase(i);
        }
    }

    // release everything (outside of the lock).
    for (auto &i: refs) {
        i.second.releaseHeldValue();
    }
}

可以看出最后会释放关联哈希表中的值。

你可能感兴趣的:(0x002 runtime Associate方法关联的对象,是否需要在dealloc中释放?)