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
中以对象self
为key
,To
为value
;
在To
中以kLGProperty
为key
,lgProperty
为value
;
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();
}
}
可以看出最后会释放关联哈希表中的值。