网站首页 网站地图
网站首页 > 手机游戏 > 如何记录ios游戏帧率

如何记录ios游戏帧率

时间:2026-03-17 12:40:49

在 iOS 游戏中记录帧率(FPS)是一个常见的需求,用于优化性能、调试帧率波动、确保游戏流畅运行等。以下是如何在 iOS 中记录游戏帧率的几种常见方法,适用于 Objective-C、Swift 和 Xcode 开发环境。

✅ 一、使用 CADisplayLink 记录帧率

CADisplayLink 是一个用于在屏幕刷新率的节奏下定时执行回调的类,非常适合用来记录帧率。

✅ 示例代码(Swift):

import UIKit

class GameViewController: UIViewController {
    var frameRate: Int = 0
    var lastTime: Double = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // 设置 CADisplayLink
        let displayLink = CADisplayLink(target: self, selector: #selector(updateFrameRate))
        displayLink.delegate = self
        displayLink.paused = true
        displayLink.isPaused = true

        // 开始显示链接
        displayLink.schedule(in: .now(), for: .ever)
    }

    @objc func updateFrameRate() {
        // 计算帧率
        let currentTime = CACurrentTime()
        let deltaTime = currentTime - lastTime

        // 假设屏幕刷新率是 60 FPS
        frameRate = Int(1.0 / (deltaTime / 60.0))

        lastTime = currentTime
    }

    // 自定义 CADisplayLink 的 delegate 方法
    func displayLink(timer: CADisplayLink) {
        updateFrameRate()
    }
}

✅ 说明:

  • CADisplayLink 会以屏幕刷新率(通常为 60 FPS)自动调用 updateFrameRate
  • 每次调用 updateFrameRate 时,计算当前时间与上一次的时间差。
  • 通过 1.0 / (deltaTime / 60.0) 计算出每秒的帧数,单位为 FPS。

✅ 二、使用 DispatchQueueTimer 记录帧率

如果你不想使用 CADisplayLink,也可以使用 DispatchQueueTimer 来记录帧率。

✅ 示例代码(Swift):

import UIKit

class GameViewController: UIViewController {
    var frameRate: Int = 0
    var lastTime: Double = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // 使用 Timer 计算帧率
        let timer = Timer.init(deadline: .now(), interval: 1.0 / 60.0, repeats: true)
        timer.fire()

        // 保存当前时间
        lastTime = CACurrentTime()
    }

    func updateFrameRate() {
        let currentTime = CACurrentTime()
        let deltaTime = currentTime - lastTime

        frameRate = Int(1.0 / (deltaTime / 60.0))

        lastTime = currentTime
    }
}

✅ 说明:

  • 使用 Timer 每秒触发一次,计算帧率。
  • 通过 1.0 / (deltaTime / 60.0) 计算出每秒的帧数。

✅ 三、使用 CVPixelBufferCFAbsoluteTime 记录帧率(更精确)

如果你需要更精确的帧率记录(例如在游戏循环中),可以使用 CVPixelBufferCFAbsoluteTime

✅ 示例代码(Swift):

import UIKit
import CoreVideo

class GameViewController: UIViewController {
    var frameRate: Int = 0
    var lastTime: Double = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // 使用 CFAbsoluteTime 计算帧率
        let startTime = CFAbsoluteTime()

        // 在游戏循环中执行
        while true {
            let endTime = CFAbsoluteTime()
            let deltaTime = endTime - startTime

            frameRate = Int(1.0 / (deltaTime / 60.0))

            // 重置时间
            startTime = endTime
        }
    }
}

✅ 说明:

  • CFAbsoluteTime 是 macOS 和 iOS 中的高精度时间函数,可以用于更精确的帧率计算。

✅ 四、使用 NSRunLoopNSOperationQueue 记录帧率

如果你在游戏主循环中运行,可以使用 NSRunLoop 来确保帧率的稳定。

import UIKit

class GameViewController: UIViewController {
    var frameRate: Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // 设置 NSRunLoop
        let runLoop = NSRunLoop.currentRunLoop()
        runLoop.add(self, forMode: .commonModes)

        // 启动运行循环
        runLoop.run()
    }

    @objc func updateFrameRate() {
        let currentTime = CACurrentTime()
        let deltaTime = currentTime - lastTime

        frameRate = Int(1.0 / (deltaTime / 60.0))

        lastTime = currentTime
    }
}

✅ 五、使用 GCD 记录帧率(适用于游戏主循环)

如果你在游戏主循环中运行,可以使用 DispatchQueue 来记录帧率。

import UIKit

class GameViewController: UIViewController {
    var frameRate: Int = 0
    var lastTime: Double = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // 使用 GCD 计算帧率
        DispatchQueue.global(qos: .userInitiated).async {
            self.updateFrameRate()
        }
    }

    @objc func updateFrameRate() {
        let currentTime = CACurrentTime()
        let deltaTime = currentTime - lastTime

        frameRate = Int(1.0 / (deltaTime / 60.0))

        lastTime = currentTime
    }
}

✅ 总结

方法 优点 缺点
CADisplayLink 适合游戏主循环,自动与屏幕刷新率同步 需要处理 displayLink 的生命周期
Timer 简单易用 需要手动管理时间
CFAbsoluteTime 精度高 需要处理时间计算
NSRunLoop 适合游戏主循环 需要处理运行循环
GCD 简单 依赖于 GCD 的调度机制

✅ 推荐方案

  • 推荐使用 CADisplayLink,因为它直接与屏幕刷新率同步,适合游戏主循环。
  • 如果你使用的是游戏引擎(如 SpriteKit、SceneKit),可以使用引擎提供的帧率记录方法。

✅ 附:如何在 Xcode 中查看帧率

在 Xcode 中,你可以通过以下方式查看帧率:

  1. 打开你的项目,进入 Debug Navigator
  2. 找到 GameViewController 或你的游戏类。
  3. GameViewController 中添加一个 @property (nonatomic) NSInteger frameRate;
  4. updateFrameRate 方法中,将 frameRate 的值打印出来。

如需更详细的代码示例或针对特定游戏引擎的帧率记录方法,欢迎继续提问!