您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>通訊/手機(jī)編程>

對(duì) FBRetainCycleDetector 中實(shí)現(xiàn)的關(guān)聯(lián)對(duì)象機(jī)制的分析

大?。?/span>0.3 MB 人氣: 2017-09-26 需要積分:1

  FBAssociationManager is a tracker of object associations. For given object it can return all objects that are being retained by this object with objc_setAssociatedObject & retain policy.

  FBRetainCycleDetector 在對(duì)關(guān)聯(lián)對(duì)象進(jìn)行追蹤時(shí),修改了底層處理關(guān)聯(lián)對(duì)象的兩個(gè) C 函數(shù),objc_setAssociatedObject 和 objc_removeAssociatedObjects。

  FBAssociationManager

  在 FBAssociationManager 的類方法 + hook 調(diào)用時(shí),fishhook 會(huì)修改 objc_setAssociatedObject 和 objc_removeAssociatedObjects 方法:

  + (void)hook {

  #if _INTERNAL_RCD_ENABLED

  std::lock_guard《std::mutex》 l(*FB::AssociationManager::hookMutex);

  rcd_rebind_symbols((struct rcd_rebinding[2]){

  {

  “objc_setAssociatedObject”,

 ?。╲oid *)FB::AssociationManager::fb_objc_setAssociatedObject,

  (void **)&FB::AssociationManager::fb_orig_objc_setAssociatedObject

  },

  {

  “objc_removeAssociatedObjects”,

 ?。╲oid *)FB::AssociationManager::fb_objc_removeAssociatedObjects,

  (void **)&FB::AssociationManager::fb_orig_objc_removeAssociatedObjects

  }}, 2);

  FB::AssociationManager::hookTaken = true;

  #endif //_INTERNAL_RCD_ENABLED

  }

  將它們的實(shí)現(xiàn)替換為 FB::AssociationManager:: fb_objc_setAssociatedObject 以及 FB::AssociationManager::fb_objc_removeAssociatedObjects 這兩個(gè) Cpp 靜態(tài)方法。

  上面的兩個(gè)方法實(shí)現(xiàn)都位于 FB::AssociationManager 的命名空間中:

  namespace FB { namespace AssociationManager {

  using ObjectAssociationSet = std::unordered_set《void *》;

  using AssociationMap = std::unordered_map《id, ObjectAssociationSet *》;

  static auto _associationMap = new AssociationMap();

  static auto _associationMutex = new std::mutex;

  static std::mutex *hookMutex(new std::mutex);

  static bool hookTaken = false;

  。。.

  }

  命名空間中有兩個(gè)用于存儲(chǔ)關(guān)聯(lián)對(duì)象的數(shù)據(jù)結(jié)構(gòu):

  AssociationMap 用于存儲(chǔ)從對(duì)象到 ObjectAssociationSet * 指針的映射

  ObjectAssociationSet 用于存儲(chǔ)某對(duì)象所有關(guān)聯(lián)對(duì)象的集合

  其中還有幾個(gè)比較重要的成員變量:

  _associationMap 就是 AssociationMap 的實(shí)例,是一個(gè)用于存儲(chǔ)所有關(guān)聯(lián)對(duì)象的數(shù)據(jù)結(jié)構(gòu)

  _associationMutex 用于在修改關(guān)聯(lián)對(duì)象時(shí)加鎖,防止出現(xiàn)線程競(jìng)爭(zhēng)等問題,導(dǎo)致不可預(yù)知的情況發(fā)生

  hookMutex 以及 hookTaken 都是在類方法 + hook 調(diào)用時(shí)使用的,用于保證 hook 只會(huì)執(zhí)行一次并保證線程安全

  用于追蹤關(guān)聯(lián)對(duì)象的靜態(tài)方法 fb_objc_setAssociatedObject 只會(huì)追蹤強(qiáng)引用:

  static void fb_objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy) {

  {

  std::lock_guard《std::mutex》 l(*_associationMutex);

  if (policy == OBJC_ASSOCIATION_RETAIN ||

  policy == OBJC_ASSOCIATION_RETAIN_NONATOMIC) {

  _threadUnsafeSetStrongAssociation(object, key, value);

  } else {

  // We can change the policy, we need to clear out the key

  _threadUnsafeResetAssociationAtKey(object, key);

  }

  }

  fb_orig_objc_setAssociatedObject(object, key, value, policy);

  }

  std::lock_guard《std::mutex》 l(*_associationMutex) 對(duì) fb_objc_setAssociatedObject 過(guò)程加鎖,防止死鎖問題,不過(guò) _associationMutex 會(huì)在作用域之外被釋放。

非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?