图形性能对用户体验有直接的影响,Instruments中的Core Animation工具用于测量物理机上的图形性能,通过视图的刷新频率大小来判断应用的图形性能。例如一个复杂的列表滚动时它的刷新率应该努力趋近于60fps才能让用户觉得够流畅,从这个数字也可以算出run loop最长的响应时间应该是16毫秒。
怎样更直观的看到刷新率FPS?
答:FHHFPSIndicator可以用于在iOS开发中显示当前画面的FPS.
GitHub地址:https://github.com/jvjishou/FHHFPSIndicator
安装
CocoaPods
在 Podfile 中添加 pod "FHHFPSIndicator"。
执行 pod install 或 pod update。
导入 <FHHFPSIndicator/FHHFPSIndicator.h>。
手动安装
将FHHFPSIndicator文件夹中的所有源代码拽入项目中。
导入主头文件:#import "FHHFPSIndicator.h"。
使用说明
在AppDelegate.m文件中的didFinishLaunchingWithOptions方法中,当执行了[self.window makeKeyAndVisible];后,调用[[FHHFPSIndicator sharedFPSIndicator] show]。
建议:在DEBUG模式下使用显示FPS功能
#if defined(DEBUG) || defined(_DEBUG)
#import "FHHFPSIndicator.h"
#endif
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
// add the follwing code after the window become keyAndVisible
#if defined(DEBUG) || defined(_DEBUG)
[[FHHFPSIndicator sharedFPSIndicator] show];
// [FHHFPSIndicator sharedFPSIndicator].fpsLabelPosition = FPSIndicatorPositionTopRight;
#endif
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[HomeViewController alloc] init]];
return YES;
}
效果
如果想自己造一个?
答:可以用CADisplayLink 来监视 CPU 的卡顿问题
代码如下:
#import "YYFPSLabel.h"
#import <YYText.h>
#define kSize CGSizeMake(55, 20)
@implementation YYFPSLabel {
CADisplayLink *_link;
NSUInteger _count;
NSTimeInterval _lastTime;
UIFont *_font;
UIFont *_subFont;
NSTimeInterval _llll;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (frame.size.width == 0 && frame.size.height == 0) {
frame.size = kSize;
}
self = [super initWithFrame:frame];
self.layer.cornerRadius = 5;
self.clipsToBounds = YES;
self.textAlignment = NSTextAlignmentCenter;
self.userInteractionEnabled = NO;
self.backgroundColor = [UIColor colorWithWhite:0.000 alpha:0.700];
_font = [UIFont fontWithName:@"Menlo" size:14];
if (_font) {
_subFont = [UIFont fontWithName:@"Menlo" size:4];
} else {
_font = [UIFont fontWithName:@"Courier" size:14];
_subFont = [UIFont fontWithName:@"Courier" size:4];
}
__weak typeof(self) weakSelf = self;
_link = [CADisplayLink displayLinkWithTarget:weakSelf selector:@selector(tick:)];
[_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
return self;
}
- (void)dealloc {
[_link invalidate];
}
- (CGSize)sizeThatFits:(CGSize)size {
return kSize;
}
- (void)tick:(CADisplayLink *)link {
if (_lastTime == 0) {
_lastTime = link.timestamp;
return;
}
_count++;
NSTimeInterval delta = link.timestamp - _lastTime;
if (delta < 1) return;
_lastTime = link.timestamp;
float fps = _count / delta;
_count = 0;
CGFloat progress = fps / 60.0;
UIColor *color = [UIColor colorWithHue:0.27 * (progress - 0.2) saturation:1 brightness:0.9 alpha:1];
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%d FPS",(int)round(fps)]];
[text yy_setColor:color range:NSMakeRange(0, text.length - 3)];
[text yy_setColor:[UIColor whiteColor] range:NSMakeRange(text.length - 3, 3)];
text.yy_font = _font;
[text yy_setFont:_subFont range:NSMakeRange(text.length - 4, 1)];
self.attributedText = text;
}
使用方法:
@property (nonatomic, strong) YYFPSLabel *fpsLabel;
_fpsLabel = [YYFPSLabel new];
[_fpsLabel sizeToFit];
_fpsLabel.bottom = 100;
_fpsLabel.left = 10;
_fpsLabel.alpha = 1;
[self.view addSubview:_fpsLabel];
缺点:
日常使用差不多够用,但不是十分准确
结尾
优化的办法还是有很多,工具只是辅助,最后还是推荐大家用 Xcode自带Instuments 的 GPU Driver 预设,能够实时查看到 CPU 和 GPU 的资源消耗。在这个预设内,你能查看到几乎所有与显示有关的数据,比如 Texture 数量、CA 提交的频率、GPU 消耗等,在定位界面卡顿的问题时,这是最好的工具。
我是写代码的凡,如有错误,欢迎指正!🙂🙂🙂