iOS开发-自己写一个实时显示fps帧数的小控件

在开发中,实时的显示当前的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 = 刷新次数 / 间隔时间

你可能感兴趣的:(iOS开发-自己写一个实时显示fps帧数的小控件)