我们的目的是测试APP的FPS,而FPS是需要每时每刻都要显示的,我们可以把某个事件添加到RunLoop的commonMode中去一直监听FPS值改变,因为commonMode是一种特殊的mode,会把我们的事件添加到所有的mode中,无论用户在滑动还是停止都会进行该事件监听
苹果提供CADisplayLink,为我们测试屏幕每帧的刷新率,下面是苹果的描述
Class(CADisplayLink) representing a timer bound to the display vsync. *
那现在我们来整理一下思路,为了更友好的显示FPS,我们可以设置一个Label类这样就可以直接展现在屏幕上面了
-
FPSLabel里面需要有几个属性去计算FPS值,首先需要一个CADisplayLink,我们可以在label调用init的时候就把它添加添加到commonMode
-
我们设置一个lastTime用与计算完这一秒后,下一秒的继续计算(比如计算完第0秒到第1秒为多少帧,我们下次要把lastTime置为第1秒而不是第0秒)
-
我们设置一个count用来记录一秒内刷新了多少帧
import UIKit
class FPSLabel: UILabel {
private var link:CADisplayLink?
private var lastTime:TimeInterval = 0.0;
private var count:Int = 0;
override init(frame: CGRect)
{
super.init(frame: frame)
link = CADisplayLink.init(target: self, selector:
//commom会无论用户的app处于什么停止还是滑动都会进行fps打印(commonMode会添加timer到所有mode上面)
//receiver是指didTick方法
link?.add(to: RunLoop.current, forMode: .common)
}
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
@objc func didTick(link:CADisplayLink) {
if lastTime == 0
{
lastTime = link.timestamp
//print("lastTime \(lastTime)")
return
}
//用来记录一秒进入这个方法多少次,如果进入了20次那么count就变成20,20帧
count += 1
//在一秒内打印的次数
let delta = link.timestamp - lastTime
//print("link.timestamp \(link.timestamp) lastTime\(lastTime)")
if delta < 1{
//不够一秒就返回,继续往上面count加一,这样就可以获得一秒内有多少个页面
return
}
//这时候已经到一秒了,我们先把lastTime更新至当前时间以便下一次计算
lastTime = link.timestamp
//delta是1.0000000....
print("delta :\(delta)")
let fps = Double(count)/delta
count = 0
text = String.init(format: "%02.0f帧", round(fps))
print(text ?? "0")
}
/*
Only override draw() if you perform custom drawing.
An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
Drawing code
}
*/
}