在开发中,实时的显示当前的fps能够使我们更加直接的了解app当前的性能及运行状况,代码如下:
FPSLabel.swift
import UIKit
class FPSLabel: UILabel {
fileprivate var displayLink: CADisplayLink?
fileprivate var lastTime: TimeInterval = 0
fileprivate var count: Int = 0
deinit {
displayLink?.invalidate()
}
override func didMoveToSuperview() {
frame = CGRect(x: 15, y: 150, width: 40, height: 40)
layer.cornerRadius = 20
clipsToBounds = true
backgroundColor = UIColor.black
textColor = UIColor.green
textAlignment = .center
font = UIFont.systemFont(ofSize: 24)
run()
}
func run() {
displayLink = CADisplayLink(target: self, selector: #selector(FPSLabel.tick(_:)))
displayLink?.add(to: .current, forMode: .commonModes)
}
@objc func tick(_ displayLink: CADisplayLink) {
if lastTime == 0 {
lastTime = displayLink.timestamp
return
}
count += 1
let timeDelta = displayLink.timestamp - lastTime
if timeDelta < 0.25 {
return
}
lastTime = displayLink.timestamp
let fps: Double = Double(count) / timeDelta
count = 0
text = String(format: "%.0f", fps)
textColor = fps > 50 ? UIColor.green : UIColor.red
}
}
然后在我们的BaseViewController添加如下代码
class BaseViewController: UIViewController {
#if DEBUG
private lazy var newFpsLabel: FPSLabel = {
let label = FPSLabel()
return label
}()
#endif
override func viewDidLoad() {
super.viewDidLoad()
#if DEBUG
view.addSubview(newFpsLabel)
#endif
}
}
OC版代码如下
#import "TJBLFpsLabel.h"
@interface TJBLFpsLabel ()
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic, assign) NSTimeInterval lastTime;
@property (nonatomic, assign) int count;
@end
@implementation TJBLFpsLabel
- (void)didMoveToSuperview {
self.frame = CGRectMake(15, 150, 80, 40);
self.layer.cornerRadius = 20;
self.layer.masksToBounds = YES;
self.backgroundColor = [UIColor blackColor];
self.textColor = [UIColor greenColor];
self.textAlignment = NSTextAlignmentCenter;
self.font = [UIFont systemFontOfSize:24];
[self run];
}
- (void)run {
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)tick:(CADisplayLink *)sender {
if (_lastTime == 0) {
_lastTime = _displayLink.timestamp;
return;
}
_count += 1;
NSTimeInterval timeDelta = _displayLink.timestamp - _lastTime;
if (timeDelta < 0.25) {
return;
}
_lastTime = _displayLink.timestamp;
double fps = (double)_count / timeDelta;
_count = 0;
self.text = [NSString stringWithFormat:@"%.1f",fps];
self.textColor = fps > 50 ? UIColor.greenColor : UIColor.redColor;
}
@end
添加
#ifdef DEBUG
UIWindow *window = [UIApplication sharedApplication].keyWindow;
TJBLFpsLabel *fpsLabel = [[TJBLFpsLabel alloc] init];
[window addSubview:fpsLabel];
[window bringSubviewToFront:fpsLabel];
#endif
trick函数原理
CADisplayLink 的调用频率始终和屏幕刷新的刷新的频率一致
fps = 刷新次数 / 间隔时间