项目开发都会做一些调试, 比如看看 FPS 的情况. 网上有不少工具, 自己就参考做了一个比较简单的工具 https://github.com/remember17/WHDebugTool , 可以监测内存, CPU 和 FPS. GitHub 地址: https://github.com/remember17/WHDebugTool
1, 快速使用
1.1 pod 或直接把文件拖入项目
如果 pod 找不到 WHDebugTool, 就先 pod setup
pod 'WHDebugTool', '~> 1.2'
复制代码
1.2 导入头文件
如果是 pod 进项目:
#import <WHDebugTool/WHDebugToolManager.h>
复制代码
如果是直接把文件拖入项目:
#import "WHDebugToolManager.h"
复制代码
1.3 调用开关方法 一行代码开启或关闭监测.
- // 这个方法调用的时候会判断监测是不是处于打开的状态, 如果打开了则关闭, 如果没有打开就开启.
- [[WHDebugToolManager sharedInstance] toggleWith:DebugToolTypeAll];
复制代码
1.4 可选: 也可以通过如下方式初始化和关闭
- // 打开
- - (void)showWith:(DebugToolType)type;
- // 关闭
- - (void)hideWith:(DebugToolType)type;
复制代码
2. 参数说明
初始化方法中带有一个枚举参数 这个参数可以让三种监测随意组合. 例如只想要监测 FPS, 就传入 DebugToolTypeFPS
- DebugToolTypeAll = 0, // FPS & Memory & CPU
- DebugToolTypeFPS, // FPS
- DebugToolTypeMemory, // Memory
- DebugToolTypeCPU, // CPU
- DebugToolTypeFPSMemory, // FPS & Memory
- DebugToolTypeFPSCPU, // FPS & CPU
- DebugToolTypeCPUMemory, // Memory & CPU
复制代码
3. 实现方法
3.1 FPS 实现方法 (参考了 YYKit 中的检测工具)
首先简单介绍一下 FPS:
FPS 的意思是: 每秒传输帧数 (刷新率). 值越高, 画面越流畅, 值越低越卡顿.
下面来看一下 iOS 实现检测 FPS 的原理:
主要用的是 CADisplayLink: 一个和屏幕刷新率相同定时器. 创建 CADisplayLink 对象的时候会指定一个 selector, 把创建的 CADisplayLink 对象加入 runloop, 所以就实现了以屏幕刷新的频率调用某个方法. 在调用的方法中计算执行的次数, 用次数除以时间, 就算出了 FPS. 注: iOS 正常刷新率为每秒 60 次.
- - (void)setDisplayLink {
- // 初始化 CADisplayLink
- _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTicks:)];
- // 把 CADisplayLink 对象加入 runloop
- [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
- }
- - (void)displayLinkTicks:(CADisplayLink *)link {
- // 累加方法执行的次数
- _performTimes ++;
- if (_lastTimestamp == 0) {
- _lastTimestamp = link.timestamp;
- return;
- }
- // 记录执行的时间
- NSTimeInterval interval = link.timestamp - _lastTimestamp;
- // 当时间经过一秒的时候再计算 FPS, 否则计算的太过频繁
- if (interval>= 1) {
- // iOS 正常刷新率为每秒 60 次, 执行次数 / 时间
- float fps = _performTimes / interval;
- // 重新初始化记录值
- _performTimes = 0;
- _lastTimestamp = link.timestamp;
- // 把计算的值传出去
- if (self.fpsBlock) {
- self.fpsBlock(fps);
- }
- }
- }
复制代码
3.2 内存监测实现方法
- - (float)getUsedMemory {
- task_basic_info_data_t taskInfo;
- mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
- kern_return_t kernReturn = task_info(mach_task_self(),
- TASK_BASIC_INFO,
- (task_info_t)&taskInfo,
- &infoCount);
- if (kernReturn != KERN_SUCCESS) { return NSNotFound; }
- return taskInfo.resident_size/1024.0/1024.0;
- }
复制代码
3.3 CUP 检测实现方法
- float cpu_usage() {
- kern_return_t kr;
- task_info_data_t tinfo;
- mach_msg_type_number_t task_info_count;
- task_info_count = TASK_INFO_MAX;
- kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
- if (kr != KERN_SUCCESS) {
- return -1;
- }
- task_basic_info_t basic_info;
- thread_array_t thread_list;
- mach_msg_type_number_t thread_count;
- thread_info_data_t thinfo;
- mach_msg_type_number_t thread_info_count;
- thread_basic_info_t basic_info_th;
- uint32_t stat_thread = 0;
- basic_info = (task_basic_info_t)tinfo;
- kr = task_threads(mach_task_self(), &thread_list, &thread_count);
- if (kr != KERN_SUCCESS) {
- return -1;
- }
- if (thread_count> 0)
- stat_thread += thread_count;
- long tot_sec = 0;
- long tot_usec = 0;
- float tot_cpu = 0;
- int j;
- for (j = 0; j <thread_count; j++)
- {
- thread_info_count = THREAD_INFO_MAX;
- kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
- (thread_info_t)thinfo, &thread_info_count);
- if (kr != KERN_SUCCESS) {
- return -1;
- }
- basic_info_th = (thread_basic_info_t)thinfo;
- if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
- tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
- tot_usec = tot_usec + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds;
- tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
- }
- }
- kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
- assert(kr == KERN_SUCCESS);
- return tot_cpu;
- }
复制代码
后记
https://github.com/remember17/WHDebugTool 内存监测的值与 Xcode 给的有出入, 所以这些工具给出的值仅供参考. CUP 和 FPS 的检测结果相对来说比较接近.
我的 GitHub:https://github.com/remember17
来源: https://juejin.im/post/5b519dace51d4519956723ba