Inserts key,value pair into the map if the key isn't already in the map. The value is constructed in-place if the key is not in the map, otherwise it is not moved.
一次 set 两次调用了 try_emplace
通过代码可以看出,一次set关联值,会调用两次 try_emplace。
auto refs_result = associations.try_emplace(disguised, ObjectAssociationMap{});
只用来检查是否存在关联对象的 keyObjectAssociationMap{} 是个空的不做处理
auto result = refs.try_emplace(key, std::move(association));
这里才是真的设置 value
触发set
通过调用 LookupBucketFor 查找表中是否已经存在了对应的关联对象。
第一次调用set方法
第二次调用set方法
2.3 LookupBucketFor
和查找方法缓存的算法基本一致。
2.4 InsertIntoBucket
插入表中
template <typenameKeyArg,typename... ValueArgs>BucketT*InsertIntoBucket(BucketT*TheBucket,KeyArg&&Key,ValueArgs&&... Values) {TheBucket =InsertIntoBucketImpl(Key, Key, TheBucket);// first 就是 keyTheBucket->getFirst() = std::forward<KeyArg>(Key);// second 是Value::new (&TheBucket->getSecond()) ValueT(std::forward<ValueArgs>(Values)...);return TheBucket;}
三、 关联对象释放
思考:在对象 dealloc 的时候,会自动清理管理那对象么?
3.1 dealloc
我们从 dealloc 开始找:
dealloc
_objc_rootDealloc
rootDealloc
如果有关联对象
object_dispose
objc_destructInstance
_object_remove_assocations
来释放关联对象
void_object_remove_assocations(id object,bool deallocating){ ObjectAssociationMap refs{}; { AssociationsManager manager; AssociationsHashMap &associations(manager.get()); AssociationsHashMap::iterator i =associations.find((objc_object *)object);if (i !=associations.end()) {refs.swap(i->second); // If we are not deallocating, then SYSTEM_OBJECT associations are preserved.bool didReInsert =false;if (!deallocating) {for (auto&ref: refs) {if (ref.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) {i->second.insert(ref); didReInsert =true; } } }if (!didReInsert)associations.erase(i); } } // Associations to be released after the normal ones. SmallVector<ObjcAssociation *,4> laterRefs; // release everything (outside of the lock).for (auto&i: refs) {if (i.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) { // If we are not deallocating, then RELEASE_LATER associations don't get released.if (deallocating)laterRefs.append(&i.second); } else {i.second.releaseHeldValue(); } }for (auto*later: laterRefs) {later->releaseHeldValue(); }}