FPS
全称Frames Per Second,其实就是屏幕刷新率,苹果的iphone推荐的刷新率是60Hz,也就是说GPU每秒钟刷新屏幕60次,这每刷新一次就是一帧frame,FPS也就是每秒钟刷新多少帧画面。静止不变的页面FPS值是0,这个值是没有参考意义的,只有当页面在执行动画或者滑动的时候,FPS值才具有参考价值,FPS值的大小体现了页面的流畅程度高低,当低于45的时候卡顿会比较明显。
1.内存泄露检测
方法一: 使用 instrument 检测
Analyze
静态分析查找可疑的内存泄露
1.内存泄露
oc 对象存放在堆区, 堆区是需要程序员管理的, 如果使用变量之后没有释放变量所占用的内存空间(即这块空间没有指针指向), 导致这块空间不能再被回收使用, 这就叫内存泄漏.
2.什么情况下会发生内存泄漏?
*block 的循环引用
*潜在的内存泄露:这里主要是一些非OC对象,ARC不会对它进行释放,所以造成了一直没有释放。比如一些类型:CGImageRef(对应调用CGImageRelease)、CGContextRef(对应调用CGContextRelease)CGColorSpaceRef(对应CGColorSpaceRelease) 这些都是非OC对象,所以要自己记着释放掉。
使用方法:
1.菜单 product-Analyze
2.点击左侧感叹号就可看到分析结果,如下图
蓝色线的地方就是使用 Analyze 静态分析查找出来的泄漏点,称之为"可疑泄漏点".之所以称之为"可疑泄漏点",是因为这些点未必一定泄露,确认这些点是否泄露, 还要通过 Instruments 动态分析工具的 Leaks 和 Allocations 跟踪模板. Analyze 静态分析只是一个理论上的预测过程.
Leaks
使用方法.png 设置.png方法二: MLeaksFinder
腾讯开发的 MLeaksFinder 使用很方便, 详细了解移步于此 MLeaksFinder:精准 iOS 内存泄露检测工具, 下面介绍一下我的使用过程, 分享一些内存泄露的例子.
1.1 UIAlertController 泄露
泄露截图.png思路
- 在 viewController 中使用 dealloc 方法检测, 发现控制器没有被销毁,也出现了内存泄漏。猜测是UIAlertController 对控制器进行强引用。 看看我的代码,看出来问题出在哪里了吧!
UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self judgeAuthorization];
}];
UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"去相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
[self showImagePickerController];
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[alertVc dismissViewControllerAnimated:YES completion:nil];
}];
[alertVc addAction:action1];
[alertVc addAction:action2];
[alertVc addAction:cancelAction];
[self presentViewController:alertVc animated:YES completion:nil];
是block的循环引用导致了内存泄漏,解决办法就是用`__weak typeof(self) weakSelf = self;
[weakSelf judgeAuthorization];
[weakSelf showImagePickerController];
循环引用示意图.png
- vc 的内存泄露解决了,不过在点击确定类 Action push 到下一个 vc 时, 仍然报alertVc 内存泄露, 如何证明呢?相信你也一定想到,写一个类继承自UIAlertController 看看有没有走dealloc方法...... 然而.....真的没有。
想了一下, 原来是因为[self presentViewController:alertVc animated:YES completion:nil]
vc 对 alertVc 在进行着强引用, 而 vc 还没有被释放, 所以 alertVc 无法释放。在 Google 后找到解决办法, 声明全局变量, 修改 dismiss 时的 alertVc。
@property (strong, nonatomic) XSAlertController *alertController;
[weakSelf.alertController dismissViewControllerAnimated:YES completion:nil];
//之前是 [alertVc dismissViewControllerAnimated:YES completion:nil];
在pop alertVc 所在的 vc 时, alertVc 调用了 dealloc 方法, MLeaksFinder 又弹框了, 没有泄漏 MLeaksFinder 为什么还弹框, 难道是我释放多了一次?
莫慌, 其实是 MLeaksFinder 的友情提示, 告诉你刚刚内存泄漏的对象现在已经正常释放了,详细的解释请看这里MLeaksFinder 新特性
2. 启动时间优化
在 scheme 中添加 DYLD_PRINT_STATISTICS
设置为1
输出控制台会显示时间
console.png
3. UI 卡顿优化
CPU 资源消耗原因和解决方案
对象创建
对象的创建会分配内存、调整属性、甚至还有读取文件等操作,比较消耗 CPU 资源。尽量用轻量的对象代替重量的对象,可以对性能有所优化。比如 CALayer 比 UIView 要轻量许多,那么不需要响应触摸事件的控件,用 CALayer 显示会更加合适。如果对象不涉及 UI 操作,则尽量放到后台线程去创建,但可惜的是包含有 CALayer 的控件,都只能在主线程创建和操作。通过 Storyboard 创建视图对象时,其资源消耗会比直接通过代码创建对象要大非常多,在性能敏感的界面里,Storyboard 并不是一个好的技术选择。
Allocations
查看内存分配
All Heap Allocations: 真实内存
All Anonymous VM: 虚拟内存, 为程序分配的虚拟内存,当程序有需要的时候,能够及时为程序提供足够的内存空间,而不会现用现创建
在我的项目中进行选择相册照片的操作, 内存分配如图所示, 红框选中的就是虚拟内存项
虚拟内存.png
VM:CG raster data
关于这个问题我在google中找到了解释,这是SDWebImage的问题
- Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory.
- Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
//所以我们需要在Appdelegate中设置一下
[SDImageCache sharedImageCache].config.shouldDecompressImages = NO;
Time Profiler
检测应用CPU的使用情况
注意点:
(1)使用真机调试。
(2)最好使用release包测试(release是发布版本,苹果会在release包中做很多优化工作,因此用release包测试出来的性能才是最真实的)。
网友评论