0

我遇到的问题似乎只发生在设备上,而不是模拟器上。

我的应用程序的动画使用以下方法启动和停止:

NSTimer* animationTimer;

-(void)startAnimation
{
    if(animationTimer == nil)
        animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(drawView) userInfo:nil repeats:YES];
}

-(void)stopAnimation
{
    [animationTimer invalidate];
    animationTimer = nil;
}

在模拟器中,这可以正常工作,并且 drawView 开始以 60fps 的速度被调用。在设备上(在 iPod Touch 上测试), scheduleTimerWithTimeInterval 方法似乎不起作用。此外,[animationTimer invalidate] 会导致 EXC_BAD_ACCESS。

我发现了一个明显但很小的缺陷;将 if(animationTimer != nil) 添加到 stopAnimation 方法将防止崩溃,但不能解决动画计时器未正确初始化的问题。

编辑:以上内容并不能防止崩溃。animationTimer != nil 但调用无效会导致 EXC_BAD_ACCESS。

还应该补充一点,这个问题不会一直在设备上发生。也许有 40% 的时间。

4

2 回答 2

3

如果animationTimer完全按照您的说明声明,那么它的初始值是未定义的。消息传递一个与分配的 Objective-C 对象不对应的指针值很可能会给你EXC_BAD_ACCESS. 您应该将其初始值显式设置为nil,或考虑将其声明为类的成员变量,以便在nil分配对象时将其与其他成员变量一起初始化为 0/。

于 2010-05-08T15:37:25.070 回答
0

定时器不是实时机制;它仅在已添加计时器的运行循环模式之一正在运行并且能够检查计时器的触发时间是否已过时触发。由于典型的运行循环管理的各种输入源,计时器的时间间隔的有效分辨率被限制在 50-100 毫秒的数量级。如果在长时间调用期间或运行循环处于不监视计时器的模式下发生计时器的触发时间,则计时器不会触发,直到下一次运行循环检查计时器。因此,定时器触发的实际时间可能是计划触发时间之后的一个重要时间段。

请记住,NSTimer 并不总是“准时”触发。您的应用程序可以在模拟器上运行,因为它有大量可用资源 - Mac 上几乎可以使用整个处理器和 RAM。另一方面,该设备的可用资源数量有限。这可能会导致您的应用程序中出现某种竞争条件。

另一件事是您没有保留计时器(这是一件好事),因此唯一声称拥有它的对象是您当前的运行循环。当您调用 [timer invalidate] 时;计时器被释放。[timer invalidate] 很有可能您的计时器已在其他地方释放;功能。试图使已经失效的计时器失效将导致符合您描述的错误。

总体而言,请查看您的代码中的计时器可能已失效的其他地方。还要检查比赛条件。

希望这有帮助,保罗

于 2010-05-07T08:39:07.747 回答