NSTimer 延迟 - iPhone SDK
我制作了一个在整个代码中使用许多计时器的游戏。然而,计时器必须在如此短的时间内处理许多任务,这导致了我的游戏出现延迟的问题。例如,我的计时器以 (0.05) 的间隔运行,它需要绘制和更新屏幕上的许多图像。有什么办法可以分配工作流程,使程序运行得更顺畅吗?
谢谢
凯文
I made a game that uses many timers throughout the code. However the timer has to deal with many tasks in such a small amount of time which leads to the problem where there is lag in my game. For example, my timer runs at an interval of (0.05) and it needs to draw and update many of the images on the screen. Is there any way I can distribute the work flow so that the program runs much smoother?
Thanks
Kevin
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会使用
NSThread
而不是NSTimer
。我在这个领域使用 NSThread 取得了更多成功,因为它在独立线程上运行,并且不会从主 ui 线程中触发。在线程循环中休眠 1/20(你的 0.05)秒。由于该线程不在 UI 线程上运行,因此它的所有任务都不应该减慢您的 UI 速度。但是,由于它不在 UI 上运行,因此您必须调用performSelectorOnMainThread 才能从该后台线程更新 UI。我在我的更新方法(一个简单的布尔值)上加了一个锁,表示如果上次用户界面更新尚未发生,则跳过此更新。然后,如果我的处理时间不够了,我就在这里或那里丢一两帧。在重画之前,我还会做很多检查,看看是否有任何实际变化。I would use an
NSThread
instead of anNSTimer
. I have had more success in this area using NSThread because it runs on an independant thread and is not fired off your main ui thread. In the loop for the thread sleep it for 1/20 (your 0.05) of a second. Because the thread is not running on the UI thread all of its tasks should not slow your UI down. However beacsue it is not running on the UI you will have to callperformSelectorOnMainThread
to get the UI to update from this background thread. I put a lock on my update method (a simple boolean) that says if the last ui update has not happened, just skip this one. then if im running out of processing time i just drop a frame or two here and there. I also do a lot of checking to see if anything has actually changed before i redraw.简单的解决方案:放弃 NSTimer。
将重绘代码移至单个方法,然后使用 CADisplayLink。使用
NSTimer
方法的问题是,对于屏幕来说,所有内容的重绘速度太快或太慢。通过使用CADisplayLink,您可以将重绘代码与屏幕刷新率同步。然后您需要做的就是修改您的代码,以便它可以处理在特定时间不被调用的情况。是的,请检查以确保您不需要像 Aran Mulholland 上面所说的那样重新绘制。只要确保检查的时间不会像重新提款一样长。
并记住优化您的代码。很多。使用 ivars 访问对象,但使用整个属性 (self.myObject =) 来设置对象。
Simple solution: Ditch NSTimer.
Move your redrawing code to a single method, then use
CADisplayLink
. The issue with using yourNSTimer
approach is that everything is being redrawn too fast or too slow for the screen. By using CADisplayLink, you can synchronize your redraw code to the screen refresh rate. All you need to do then is touch up your code so that it can deal with not being called at a specific time.And yes, check to make sure you don't need to redraw as Aran Mulholland said above. Just make sure the checks don't take as long as a redraw.
And remember to optimize your code. A lot. Use ivars to access objects, but the whole property (self.myObject =) to set your objects.