obj*_*001 6 objective-c ios cadisplaylink
我CADisplayLink在我的iPhone应用程序中使用.
这是相关代码:
SMPTELink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onTick)];
SMPTELink.frameInterval = 2;//30fps 60/n = fps
[SMPTELink addToRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
Run Code Online (Sandbox Code Playgroud)
因此onTick被称为30FPS(1/30秒)的每一帧.这在iOS6+上很有效 - 完全符合我的需要.但是,当我在运行iOS5.1的iPhone 4s上运行我的应用程序时,onTick方法的运行速度比使用iOS6版本略慢.几乎就像是在运行它29FPS.稍微过了一点,它与iOS6 iPhone 5不同步.
onTick方法中的代码并不耗时(这是我的一个想法...),而且它不是iPhone,因为应用程序在运行iOS6的iPhone 4上运行良好.
请问CADisplayLink功能不同的iOS5.1?任何可能的解决方法/解决方案?
Rob*_*Rob 19
我无法谈论iOS 5.xv 6.x的差异,但是当我使用时CADisplayLink,我从不硬编码像每次迭代"移动x像素/点"这样的东西,而是我看timestamp(或更准确地说,三角洲)在我的初始timestamp和当前之间timestamp)并根据经过的时间计算位置,而不是通过多少帧.这样,帧速率不会影响运动的速度,而只会影响它的平滑度.(并且30和29之间的差异可能难以区分.)
一旦显示链接与运行循环相关联,当需要更新屏幕内容时,将调用目标上的选择器.目标可以读取显示链接的timestamp属性以检索上一帧显示的时间.例如,显示电影的应用程序可能会使用时间戳来计算下一个要显示的视频帧.执行其自己的动画的应用程序可能使用时间戳来确定显示对象在即将到来的帧中的显示位置和方式.的持续时间属性提供的帧之间的时间量.您可以在应用程序中使用此值来计算显示的帧速率,下一帧将显示的大致时间,以及调整绘图行为以便及时准备下一帧以进行显示.
作为一个随机的例子,我在这里UIBezierPath使用经过的秒数作为参数设置动画.
或者,或者,如果您正在处理一系列UIImage帧,则可以按如下方式计算帧编号:
@property (nonatomic) CFTimeInterval firstTimestamp;
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
if (!self.firstTimestamp)
self.firstTimestamp = displayLink.timestamp;
CFTimeInterval elapsed = (displayLink.timestamp - self.firstTimestamp);
NSInteger frameNumber = (NSInteger)(elapsed * kFramesPerSecond) % kMaxNumberOfFrames;
// now do whatever you want with this frame number
}
Run Code Online (Sandbox Code Playgroud)
或者,更好的是,为了避免丢失帧的风险,继续让它以60 fps运行并确定帧是否需要更新,这样你就可以降低丢帧的风险.
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
if (!self.firstTimestamp)
self.firstTimestamp = displayLink.timestamp;
CFTimeInterval elapsed = (displayLink.timestamp - self.firstTimestamp);
NSInteger frameNumber = (NSInteger)(elapsed * kFramesPerSecond) % kMaxNumberOfFrames;
if (frameNumber != self.lastFrame)
{
// do whatever you want with this frame number
...
// now update the "lastFrame" number property
self.lastFrame = frameNumber;
}
}
Run Code Online (Sandbox Code Playgroud)
但通常情况下,根本不需要帧数.例如,要移动一个UIView圆圈,您可能会执行以下操作:
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
if (!self.firstTimestamp)
self.firstTimestamp = displayLink.timestamp;
CFTimeInterval elapsed = (displayLink.timestamp - self.firstTimestamp);
self.animatedView.center = [self centerAtElapsed:elapsed];
}
- (CGPoint)centerAtElapsed:(CFTimeInterval)elapsed
{
CGFloat radius = self.view.bounds.size.width / 2.0;
return CGPointMake(radius + sin(elapsed) * radius,
radius + cos(elapsed) * radius);
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果你使用仪器测量帧速率,它看起来可能比它在设备上的速度慢.对于matt的评论,对于准确的帧速率,您应该在具有发布版本的实际设备上以编程方式进行测量.
| 归档时间: |
|
| 查看次数: |
5889 次 |
| 最近记录: |