追根问底:Objective-C 关联属性基本原理分析
2025-02-19 网络
// 2.检测现阶段;也确实不意味着关连性特点,某些类不意味着其实例有关连性特点if(object->getIsa->forbidsAssociatedObjects) _objc_fatal( "objc_setAssociatedObject called on instance (%p) of class %s which does not allow associated objects", object, object_getClassName(object)); // 3.创建者一个纸制;也指针的构造;也,磁盘要关连性的;也指针DisguisedPtr disguised{(objc_object *)object};// 4.创建者一个纸制关连性意图和被关连性最大值的;也ObjcAssociation association{policy, value};
// 5.根据关连性意图来对最大值开展摘录(retain或copy)association.acquireValue;
boolisFirstAssociation = false; {// 6.利用关连性管理工作器及其之前的关连性所列;也AssociationsManager manager;AssociationsHashMap Brown associations(manager.get);
// 7.最大值如果普遍存在,则开展关连性if(value) { // 8.无论如何向所列之前嵌入现阶段要关连性的;也和最大值,如果现在普遍存在,则什么都不认真autorefs_result = associations.try_emplace(disguised, ObjectAssociationMap{}); // 9. 检测try_emplace工具的嵌入结果,如果认真了嵌入转换,则标记首次关连性为trueif(refs_result.second) { isFirstAssociation = true; }
// 10.将所列之前磁盘的最大值与key开展关连性autoBrownrefs = refs_result.first->second; autoresult = refs.try_emplace(key, std::move(association)); // 11.如果key现在普遍存在,则开展关连性意图和关连性最大值的对等if(!result.second) { association.swap(result.first->second);}// 12. 要关连性的最大值为nil,则为拔除转换} else{ // 13. 载入到关连性到此;也的特点对autorefs_it = associations.find(disguised); if(refs_it != associations.end) { // 14.有关连性特点,利用磁盘key的所列autoBrownrefs = refs_it->second; // 15.载入完全一致key确实普遍存在autoit = refs.find(key); if(it != refs.end) { // 16.普遍存在则开展关连性统计数据的替换,有数关连性意图和最大值,此时其实是将最大值搬走了association.swap(it->second);// 17.就其载入转换refs.erase(it);if(refs.size == 0) { associations.erase(refs_it);}}}}}
// 18.正确确实为此类实例;也的第一次关连性,如果是,则修改标记位,标明现在有关连性特点if(isFirstAssociation) object->setHasAssociatedObjects;
// 19.将旧的最大值开展release,如果必需的话association.releaseHeldValue;}
可以看着,整个关连性特点的全过程非常简洁,对于新最大值确实必需 retain 以及旧最大值确实必需 release,是由关连性意图立即的:
enum{ OBJC_ASSOCIATION_SETTER_ASSIGN= 0, // assgin特点OBJC_ASSOCIATION_SETTER_RETAIN= 1, // 设置最大值的时候必需retainOBJC_ASSOCIATION_SETTER_COPY= 3, // 设置最大值的时候必需copyOBJC_ASSOCIATION_GETTER_READ= ( 0<< 8), // readonly的特点OBJC_ASSOCIATION_GETTER_RETAIN= ( 1<< 8), // 利用最大值的时候必需retainOBJC_ASSOCIATION_GETTER_AUTORELEASE= ( 2<< 8), // 利用最大值的时候必需autoreleaseOBJC_ASSOCIATION_SYSTEM_OBJECT= _OBJC_ASSOCIATION_SYSTEM_OBJECT, // 1 << 16};acquireValue 工具借助如下,其只是正确确实必需 retain 和 copy,不久加载完全一致的线性:
inlinevoidacquireValue { if(_value) { switch(_policy Brown 0xFF) { caseOBJC_ASSOCIATION_SETTER_RETAIN: _value = objc_retain(_value);break; caseOBJC_ASSOCIATION_SETTER_COPY: _value = (( id(*)( id, SEL))objc_msgSend)(_value, @selector( copy)); break; }}}在上面第 8 步之前,有加载 try_emplace 工具来将统计数据嵌入到所列构造之前,此线性嵌入时则会正确要嵌入的统计数据确实普遍存在,其返回最大值则会转告加载者确实产生了嵌入转换,如果现在普遍存在,则此线性则会什么都不认真。
三、利用和移出关连性特点的物理现象
那时候,我们现在基本清楚了关连性特点是如何设置和磁盘的,再行来解释如果利用和移出就非常容易了。
利用关连性特点的最大值是用于 objc_getAssociatedObject 试运行时工具借助的,此工具借助如下:
idobjc_getAssociatedObject( id object, constvoid*key ) {return_object_get_associative_reference( object, key); }我们还是主要来求解下其加载的_object_get_associative_reference 实际上工具:
id_object_get_associative_reference(id object, constvoid*key) {// 1.创建者关连性;也构造ObjcAssociation association{};{ // 2.利用关连性管理工作器及具体来说的Hash所列AssociationsManager manager;AssociationsHashMap Brown associations(manager.get); // 3.无论如何载入现阶段传布;也的关连性特点AssociationsHashMap::iterator i = associations.find((objc_object *)object);if(i != associations.end) { // 4.如果现阶段;也有关连性特点,无论如何载入磁盘key的列所列之前确实普遍存在传布的keyObjectAssociationMap Brownrefs = i->second;ObjectAssociationMap::iterator j = refs.find(key);if(j != refs.end) { // 5.如果可以卡斯到,对association开展赋最大值association = j->second;// 6.根据关连性意图来立即确实对返回的最大值开展retainassociation.retainReturnedValue;}}}// 7.根据返回意图来立即确实必需autorelease,如果很难卡斯到,则会返回nil最大值returnassociation.autoreleaseReturnedValue; }对于现在关连性了特点的;也,我们也可以加载 objc_removeAssociatedObjects 工具来将关连性的所有特点开展移出,此工具借助如下:
voidobjc_removeAssociatedObjects( id object) {// ;也普遍存在,并且现在标记过关连性特点if( objectBrownBrown object->hasAssociatedObjects) { _object_remove_assocations( object, /*deallocating*/false); }}_object_remove_assocation 实际上线性的借助也不复杂,求解如下:
void_object_remove_assocations(id object, booldeallocating) {// 1.创建者关连性;也ObjectAssociationMap refs{};{// 2.利用关连性管理工作器及Hash所列AssociationsManager manager;AssociationsHashMap Brown associations(manager.get); // 3.载入传布;也的关连性特点AssociationsHashMap::iterator i = associations.find((objc_object *)object);if(i != associations.end) { // 4.载入到后,用空最大值开展对等refs.swap(i->second);// 5.如果是子系统;也,则必需保持一致关连性booldidReInsert = false; if(!deallocating) { for( autoBrownref: refs) { if(ref.second.policy Brown OBJC_ASSOCIATION_SYSTEM_OBJECT) { i->second.insert(ref);didReInsert = true; }}}// 6.须要保持一致关连性,则其实拔除统计数据if(!didReInsert) associations.erase(i);}}// 7.对旧最大值开展release转换SmallVector四、关连性特点如何开展内核管理工作?
通过前面的引介,我们明白在关连性特点时,可以通过关连性意图来设置一些和内核管理工作就其的的子系统,在设置关连性特点时,如果必需的话,其实际上则会根据内核管理工作意图对旧最大值开展 release 转换,但是你确实有想过,当;也较长时间的一段时间内就此结束后,这些关连性特点迁走的的内核是如何回收的?这就必需我们从子系统的 dealloc 工具之前找出题目了。
子系统;也在丢失时,dealloc 工具终于则会监督到一个名为 objc_destructInstance 的实际上线性,此线性借助如下:
void* objc_destructInstance(id obj){if(obj) { boolcxx = obj->hasCxxDtor; // 通过标记利用此;也确实有关连性特点boolassoc = obj->hasAssociatedObjects; if(cxx) object_cxxDestruct(obj); // 移铲除此;也的关连性特点if(assoc) _object_remove_assocations(obj, /*deallocating*/true); obj->clearDeallocating;}returnobj; }
其之前则会正确要丢失的;也确实有关连性特点,如果有,又则会加载到_object_remove_assocation 线性来开展关连性特点的移出,这个线性前面引介过,实际上则会处理内核管理工作问题。
五、关连性管理工作器与所列的创建者时机
在整个关连性特点借助建议书之前,还有一点我们很难级联引介,即具体来说的关连性管理工作器和 Hash 所列是怎么创建者的,何时创建者的。我们目前只看着,当要设置或利用关连性特点时,其实拿到管理工作器和 Hash 所列开展用于,并无调用。其实,这些具体来说统计数据构造的创建者在 runtime 调用时就现在完成,流程路径如下:
1. 加载 runtime 正对面线性_objc_init
2. 通告加载 map_images 线性
3. 加载 map_images_nolock 线性
4. map_images_nolock 其之前则会加载 arr_init 线性,此线性借助如下:
voidarr_init( void) {AutoreleasePoolPage::init;SideTablesMap.init;_objc_associations_init;if(DebugScanWeakTables) startWeakTableScan;}可以看着,此线性则会开展终端释放池,关连性特点等语义的调用。
END
这里有最新开源资讯、软体更新、技术零售商店等以下内容
点这里 ↓↓↓ 记得 瞩目✔ 标星⭐ 哦~
。嗓子痛咳嗽拉肚子吃什么药好
奥美拉唑胶囊用法用量
吃什么可以治疗拉肚子
日本干细胞医院排名
佐米曲普坦片的用法用量
常乐康酪酸梭菌二联活菌散怎么样
偏头痛怎么回事怎么治疗
儿科
新冠特效药有哪些
上一篇: RocketMQ之消费者激活与消费流程
- 05-11能同甘也能共苦的星座女,只要视作你就会坚定不移,遇到应当珍惜
- 05-11八字财运,易大起大落,到老终于过上好日子的二十四节气人
- 05-112022年4月底,事业有成,财富如雨下的3大虎年
- 05-112022年4月底,事业有成,富人如雨下的3大生肖
- 05-11女性眼中最值得许配的男人什么样?看这3个特质就知道了,很准!
- 05-11妇女眼中最值得嫁的男人什么样?看这3个特质就知道了,很准!
- 05-11爱憎分明,有内心深处洁癖的星座,如果爱有瑕疵,宁愿断舍离
- 05-114月16日-5月12日,开辟从新财路,财富欣欣然来临的4大生肖
- 05-114月末16日-5月末12日,开辟新财路,财富欣欣然来临的4大生肖
- 05-114同年16日-5同年12日,桃花盛开,天天开口笑的4大生肖