您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>源码下载>通讯/手机编程>

对 FBRetainCycleDetector 中实现的关联对象机制的分析

大小: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 在对关联对象进行追踪时,修改了底层处理关联对象的两个 C 函数,objc_setAssociatedObject 和 objc_removeAssociatedObjects。

  FBAssociationManager

  在 FBAssociationManager 的类方法 + hook 调用时,fishhook 会修改 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”,

  (void *)FB::AssociationManager::fb_objc_setAssociatedObject,

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

  },

  {

  “objc_removeAssociatedObjects”,

  (void *)FB::AssociationManager::fb_objc_removeAssociatedObjects,

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

  }}, 2);

  FB::AssociationManager::hookTaken = true;

  #endif //_INTERNAL_RCD_ENABLED

  }

  将它们的实现替换为 FB::AssociationManager:: fb_objc_setAssociatedObject 以及 FB::AssociationManager::fb_objc_removeAssociatedObjects 这两个 Cpp 静态方法。

  上面的两个方法实现都位于 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;

  。。.

  }

  命名空间中有两个用于存储关联对象的数据结构:

  AssociationMap 用于存储从对象到 ObjectAssociationSet * 指针的映射

  ObjectAssociationSet 用于存储某对象所有关联对象的集合

  其中还有几个比较重要的成员变量:

  _associationMap 就是 AssociationMap 的实例,是一个用于存储所有关联对象的数据结构

  _associationMutex 用于在修改关联对象时加锁,防止出现线程竞争等问题,导致不可预知的情况发生

  hookMutex 以及 hookTaken 都是在类方法 + hook 调用时使用的,用于保证 hook 只会执行一次并保证线程安全

  用于追踪关联对象的静态方法 fb_objc_setAssociatedObject 只会追踪强引用:

  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) 对 fb_objc_setAssociatedObject 过程加锁,防止死锁问题,不过 _associationMutex 会在作用域之外被释放。

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!