iOS主线程卡顿监测

iOS开发过程中,我们有时需要监控主线程的卡顿情况,本文介绍主线程卡顿的实现方法。

新建MainThreadMonitor类,并且在.h中声明方法。

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MainThreadMonitor : NSObject

+ (instancetype)sharedInstance;

- (void)start;
- (void)stop;

@end

NS_ASSUME_NONNULL_END

sharedInstance为单例方法,返回MainThreadMonitor类的实例。start为开始检测,stop为结束检测。

#import "MainThreadMonitor.h"

@interface MainThreadMonitor ()

@property(nonatomic, strong) dispatch_semaphore_t semaphore;
@property(nonatomic, assign) BOOL isMonitoring;
@property(nonatomic, assign) NSTimeInterval interval;
@property(nonatomic, assign) BOOL timeout;

@end

@implementation MainThreadMonitor

+ (instancetype)sharedInstance
{
    static MainThreadMonitor *sharedInstance = nil;
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        sharedInstance = [[MainThreadMonitor alloc] init];
    });
    
    return sharedInstance;
}

- (void)start
{
    self.isMonitoring = YES;
    self.interval = 0.08;
    self.semaphore = dispatch_semaphore_create(0);
    
    __weak typeof (self) weakSelf = self;
  
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      
        while (weakSelf.isMonitoring) {
            weakSelf.timeout = YES;
            dispatch_async(dispatch_get_main_queue(), ^{
                weakSelf.timeout = NO;
                dispatch_semaphore_signal(weakSelf.semaphore);
            });
            
            [NSThread sleepForTimeInterval:weakSelf.interval];
            
            if (weakSelf.timeout) {
                NSLog(@"Main thead is blocked");
            }
            dispatch_semaphore_wait(weakSelf.semaphore, DISPATCH_TIME_FOREVER);
        }
        
    });
}

- (void)stop
{
    self.isMonitoring = NO;
}

@end

sharedInstance使用dispatch_once_t构建了单例方法。

isMonitoring属性代表当前是否在检测主线程卡顿状态。

interval为卡顿时间,当前设置为0.08s。

semaphore为信号量,用于控制当前轮次的检测是否完成。

timeout为超时标记,如果timeout为YES,代表主线程出现了卡顿。

监控方法的实现主要原理为开辟了一个子线程,在子线程内设置一个循环,不停地监控卡顿状态。在每次循环内部,获取主线程的队列然后设置timeout为NO,子线程sleep时间设置为80ms,如果子线程sleep结束时主线程还没有设置timeout,代表当前出现了卡顿。代码内部加入了信号量semaphore,主要控制当前卡顿检测出来以后,再进行下一次检测,防止一次卡顿被多次检测。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值