美文网首页
DoraemonKit部分功能核心原理解析

DoraemonKit部分功能核心原理解析

作者: 不拘小节123456 | 来源:发表于2021-10-12 15:13 被阅读0次

1,网络监听功能
用处:网络检测,mock数据,大图片检测
原理:有一个系统类NSURLProtocol,它属于URL Loading System的一部分,默认通过NSURLSession等网络请求都是会默认创建一个NSURLProtocol实例进行操作,如果自己创建一个NSURLProtocol的子类并进行注册,就可以监听app内所有网络请求
参考:
https://blog.csdn.net/u014600626/article/details/108195234
2,判断是否卡顿主线程
DoraemonKit的实现逻辑很巧妙.有个类DoraemonPingThread,类似终端操作的ping指令,创建一个子线程,在子线程内访问主线程,如果在一定时间内访问成功则表示不卡顿,如果在一定时间内没有访问成功则代表卡顿.

- (void)main {
    //判断是否需要上报
    __weak typeof(self) weakSelf = self;
    void (^ verifyReport)(void) = ^() {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (strongSelf.reportInfo.length > 0) {
            if (strongSelf.handler) {
                double responseTimeValue = floor([[NSDate date] timeIntervalSince1970] * 1000);
                double duration = (responseTimeValue - strongSelf.startTimeValue) / 1000.0;
                strongSelf.handler(@{
                                     @"title": [DoraemonUtil dateFormatNow].length > 0 ? [DoraemonUtil dateFormatNow] : @"",
                                     @"duration": [NSString stringWithFormat:@"%.2f",duration],
                                     @"content": strongSelf.reportInfo
                                     });
            }
            strongSelf.reportInfo = @"";
        }
    };
    
    while (!self.cancelled) {
        if (_isApplicationInActive) {
            self.mainThreadBlock = YES;
            self.reportInfo = @"";
            self.startTimeValue = floor([[NSDate date] timeIntervalSince1970] * 1000);
            dispatch_async(dispatch_get_main_queue(), ^{
                self.mainThreadBlock = NO;
                verifyReport();
                dispatch_semaphore_signal(self.semaphore);
            });
            [NSThread sleepForTimeInterval:self.threshold];
            if (self.isMainThreadBlock) {
                self.reportInfo = [BSBacktraceLogger bs_backtraceOfMainThread];
            }
            dispatch_semaphore_wait(self.semaphore, dispatch_time(DISPATCH_TIME_NOW, 5.0 * NSEC_PER_SEC));
            {
                //卡顿超时情况;
                verifyReport();
            }
        } else {
            [NSThread sleepForTimeInterval:self.threshold];
        }
    }
}

3,oc内存泄漏
原理:hooknavigation相关方法(popViewControllerAnimated等相关方法),UIViewController相关方法(viewDidDisappear等相关方法),说明这个vc绑定的属性以及相关子view将要dealloc,然后通过runtime相关方法拿到这些属性和子view调用一个after延时方法,如果之后该对象dealloc了则没有内存泄漏如果没死则有.如果有则会弹出弹窗提示,并通过FBRetainCycleDetector库拿到引用环.

再说一下FBRetainCycleDetector原理:
简单说,根据传入的可能有引用循环的对象,深度遍历所有持有的属性,然后判断是不是有换.主要分为如下几类
1,block的引用属性:因为block也是对象,通过强制类型转换把block转换为BlockLiteral结构体,根据dispose_helperApi会自动管理block持有的引用对象的引用,如果是强引用,会调用release方法,根据这个现象可以判断改成员属性是不是强引用

 void **blockReference = block;
  NSIndexSet *strongLayout = _GetBlockStrongLayout(block);
  [strongLayout enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
    void **reference = &blockReference[idx];

    if (reference && (*reference)) {
      id object = (id)(*reference);

      if (object) {
        [results addObject:object];
      }
    }
  }];


static NSIndexSet *_GetBlockStrongLayout(void *block) {
  struct BlockLiteral *blockLiteral = block;

  /**
   BLOCK_HAS_CTOR - Block has a C++ constructor/destructor, which gives us a good chance it retains
   objects that are not pointer aligned, so omit them.

   !BLOCK_HAS_COPY_DISPOSE - Block doesn't have a dispose function, so it does not retain objects and
   we are not able to blackbox it.
   */
  if ((blockLiteral->flags & BLOCK_HAS_CTOR)
      || !(blockLiteral->flags & BLOCK_HAS_COPY_DISPOSE)) {
    return nil;
  }

  void (*dispose_helper)(void *src) = blockLiteral->descriptor->dispose_helper;
  const size_t ptrSize = sizeof(void *);

  // Figure out the number of pointers it takes to fill out the object, rounding up.
  const size_t elements = (blockLiteral->descriptor->size + ptrSize - 1) / ptrSize;

  // Create a fake object of the appropriate length.
  void *obj[elements];
  void *detectors[elements];

  for (size_t i = 0; i < elements; ++i) {
    FBBlockStrongRelationDetector *detector = [FBBlockStrongRelationDetector new];
    obj[i] = detectors[i] = detector;
  }

  @autoreleasepool {
    dispose_helper(obj);
  }

  // Run through the release detectors and add each one that got released to the object's
  // strong ivar layout.
  NSMutableIndexSet *layout = [NSMutableIndexSet indexSet];

  for (size_t i = 0; i < elements; ++i) {
    FBBlockStrongRelationDetector *detector = (FBBlockStrongRelationDetector *)(detectors[i]);
    if (detector.isStrong) {
      [layout addIndex:i];
    }

    // Destroy detectors
    [detector trueRelease];
  }

  return layout;
}

struct BlockLiteral {
  void *isa;  // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
  int flags;
  int reserved;
  void (*invoke)(void *, ...);
  struct BlockDescriptor *descriptor;
  // imported variables
};

struct BlockDescriptor {
  unsigned long int reserved;                // NULL
  unsigned long int size;
  // optional helper functions
  void (*copy_helper)(void *dst, void *src); // IFF (1<<25)
  void (*dispose_helper)(void *src);         // IFF (1<<25)
  const char *signature;                     // IFF (1<<30)
};

2,timer的引用属性:通过CFRunLoopTimerContext,拿到timer的content,之后拿到target对象
3,Association关联对象持有的强引用对象:通过fishhook,hook系统的api,自己存储一份关联对象的属性map
4,普通的强引用对象:通过runtime的api那个他的属性(class_copyIvarList)

相关文章

  • DoraemonKit部分功能核心原理解析

    1,网络监听功能用处:网络检测,mock数据,大图片检测原理:有一个系统类NSURLProtocol,它属于URL...

  • DoraemonKit -View Border

    DoraemonKit - View Border打开此功能会给APP所有的UI画边框 设计原理:通过runtim...

  • 学习资料汇总

    GeoHash核心原理解析 GeoHash算法学习讲解、解析及原理分析

  • RocketMQ 消息队列的核心 Broker

    《RocketMQ实战与原理解析》 前言 ​ Broker 是 RocketMQ 的核心, 大部分“重量级”工...

  • 2020-07-20

    《RocketMQ实战与原理解析》读书笔记和总结 基本介绍 核心部分 NameServer集群、Broker集群、...

  • docker进阶必读

    引用段落Docker 核心技术与实现原理深入解析Docker 架构原理

  • 19-03 Adaptive AUTOSAR 架构概述(18)-

    18 核心类型 核心类型定义了多个功能集合使用的通用类和功能,作为它们公共接口的一部分。定义核心类型的一个原理是包...

  • Express核心原理

    逐行解析Express核心原理 文章主要以一下三个部分组成 node 创建http服务 express 创建htt...

  • 3.xml中Sax解析实例

    1.Sax解析原理 2.Sax解析的功能 3.Sax解析xml的步骤 MyDefaultHander 继承 Def...

  • Spring Boot自动化配置原理

    Spring Boot启动原理解析核心注解及入口 @SpringBootApplication分解 其中@Auto...

网友评论

      本文标题:DoraemonKit部分功能核心原理解析

      本文链接:https://www.haomeiwen.com/subject/wzsdoltx.html