我們的目的是測試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
}
*/
}
複製程式碼