Iphone iOS-NSTimer-SIGABRT失效后-立即编辑DeAlloc Msg

Iphone iOS-NSTimer-SIGABRT失效后-立即编辑DeAlloc Msg,iphone,ios4,nstimer,sigabrt,Iphone,Ios4,Nstimer,Sigabrt,我将NSTimer嵌入到一个播放图像序列的类中。基本上,它循环并更改UIImageView。如果我让图像序列完成,一切都会顺利,但是。。。如果我试图在计时器播放时停止计时,我会得到一个信号灯。编辑:不再是一个sigabrt,但现在是一个DeAlloc,我无法解释 帧序列末尾的“停止”与我称之为中间序列的停止相同 那么是什么导致NSTimer中断mid函数并解除锁定呢。更重要的是,我可以看些什么来修复它 谢谢 我在这里使用一些示例代码: 编辑:我将在此处添加我认为相关的代码 //调用此方法以启动动

我将NSTimer嵌入到一个播放图像序列的类中。基本上,它循环并更改UIImageView。如果我让图像序列完成,一切都会顺利,但是。。。如果我试图在计时器播放时停止计时,我会得到一个信号灯。编辑:不再是一个sigabrt,但现在是一个DeAlloc,我无法解释

帧序列末尾的“停止”与我称之为中间序列的停止相同

那么是什么导致NSTimer中断mid函数并解除锁定呢。更重要的是,我可以看些什么来修复它

谢谢

我在这里使用一些示例代码:

编辑:我将在此处添加我认为相关的代码

//调用此方法以启动动画

- (void) startAnimating
{
    self.animationTimer = [NSTimer timerWithTimeInterval: animationFrameDuration                                         target: self                                      selector: @selector(animationTimerCallback:)                                    userInfo: NULL                                       repeats: TRUE];

    [[NSRunLoop currentRunLoop] addTimer: animationTimer forMode: NSDefaultRunLoopMode];

    animationStep = 0;

    if (avAudioPlayer != nil)
        [avAudioPlayer play];

    // Send notification to object(s) that regestered interest in a start action

    [[NSNotificationCenter defaultCenter]
     postNotificationName:ImageAnimatorDidStartNotification
     object:self];  
}

- (void) animationTimerCallback: (NSTimer *)timer {
    if (![self isAnimating])
        return;

    NSTimeInterval currentTime;
    NSUInteger frameNow;

    if (avAudioPlayer == nil) {
        self.animationStep += 1;

//      currentTime = animationStep * animationFrameDuration;
        frameNow = animationStep;
    } else {
        currentTime = avAudioPlayer.currentTime;
        frameNow = (NSInteger) (currentTime / animationFrameDuration);
    }

    // Limit the range of frameNow to [0, SIZE-1]
    if (frameNow < 0) {
        frameNow = 0;
    } else if (frameNow >= animationNumFrames) {
        frameNow = animationNumFrames - 1;
    }

    [self animationShowFrame: frameNow];
//  animationStep = frameNow + 1;

    if (animationStep >= animationNumFrames) {
        [self stopAnimating];

        // Continue to loop animation until loop counter reaches 0

        if (animationRepeatCount > 0) {
            self.animationRepeatCount = animationRepeatCount - 1;
            [self startAnimating];
        }
    }
}

- (void) stopAnimating
{
    if (![self isAnimating])
        return;

    [animationTimer invalidate];
    self.animationTimer = nil;

    animationStep = animationNumFrames - 1;
    [self animationShowFrame: animationStep];

    if (avAudioPlayer != nil) {
        [avAudioPlayer stop];
        avAudioPlayer.currentTime = 0.0;
        self->lastReportedTime = 0.0;
    }

    // Send notification to object(s) that regestered interest in a stop action

    [[NSNotificationCenter defaultCenter]
     postNotificationName:ImageAnimatorDidStopNotification
     object:self];  
}
-(无效)开始初始化
{
self.animationTimer=[NSTimer timerWithTimeInterval:animationFrameDuration目标:self选择器:@selector(animationTimerCallback:)userInfo:NULL repeats:TRUE];
[[NSRunLoop currentRunLoop]addTimer:animationTimer forMode:NSDefaultRunLoopMode];
animationStep=0;
如果(avAudioPlayer!=nil)
[avAudioPlayer play];
//向在开始操作中重新设定兴趣的对象发送通知
[[NSNotificationCenter defaultCenter]
postNotificationName:ImageAnimatordStartNotification
对象:自我];
}
-(void)animationTimerCallback:(NSTimer*)计时器{
如果(![self isAnimating])
回来
NSTimeInterval当前时间;
现在就开始;
if(avAudioPlayer==nil){
self.animationStep+=1;
//currentTime=animationStep*animationFrameDuration;
frameNow=动画步骤;
}否则{
currentTime=avAudioPlayer.currentTime;
frameNow=(NSInteger)(当前时间/动画帧持续时间);
}
//将frameNow的范围限制为[0,大小为1]
if(frameNow<0){
frameNow=0;
}else if(frameNow>=动画numframes){
frameNow=animationNumFrames-1;
}
[自动画ShowFrame:frameNow];
//animationStep=frameNow+1;
如果(animationStep>=animationNumFrames){
[自动停止动画];
//继续循环动画,直到循环计数器达到0
如果(animationRepeatCount>0){
self.animationRepeatCount=animationRepeatCount-1;
[自启动];
}
}
}
-(无效)停止设置动画
{
如果(![self isAnimating])
回来
[动画计时器失效];
self.animationTimer=nil;
animationStep=animationNumFrames-1;
[自动画ShowFrame:animationStep];
如果(avAudioPlayer!=nil){
[avAudioPlayer停止];
avAudioPlayer.currentTime=0.0;
self->lastReportedTime=0.0;
}
//向在停止操作中重新登记兴趣的对象发送通知
[[NSNotificationCenter defaultCenter]
postNotificationName:ImageAnimatordStopNotification
对象:自我];
}
Edit2:所以我在Dealoc中注释掉了一个NSAssert,注释掉它会让我们了解更多。现在进入
self.animationTimer=nil并说
***-ImageAnimator setAnimationTimer:::消息发送到解除分配的实例。


当我使计时器无效时,DeAlloc被正确调用。。。所以我在这里有点困惑。

我有一个可行但不是最优的解决方案

我刚刚添加了另一个函数,将当前帧设置为最后一帧,并根据需要结束序列


但这并不能解决为什么它会这样做的问题,如果我试图中途停止序列,它会崩溃。

好吧,我写了这段代码,所以我可以向您保证它应该工作得很好:)在使用视图之前,您需要调用stopAnimating,在dealloc中获得assert的唯一方法是在视图仍处于动画状态时取消分配视图。这是不应该发生的,这就是为什么会有断言的原因。还有一条大评论解释了这一断言,有什么不清楚的

- (void)dealloc {
  // This object can't be deallocated while animating, this could
  // only happen if user code incorrectly dropped the last ref.

  NSAssert([self isAnimating] == FALSE, @"dealloc while still animating");

  self.animationURLs = nil;
  self.imageView = nil;
  self.animationData = nil;
  self.animationTimer = nil;

  [super dealloc];
}
只要打电话:

[view stopAnimating];

在您从superview中删除视图之前,一切都会很好。

如果您使用的是SIGABRT,则通常意味着您使用的是断言。查看日志以查看断言是什么。嗯,DeAlloc中有一个NSAssert。。。对这一点的评论更能说明问题。。。现在是“self.animationTimer=nil;”并说***-ImageAnimator setAnimationTimer:::消息发送到解除分配的实例。在我使计时器无效后,正在调用DeAlloc。。。所以我在这里有点困惑。你可能正在调用计时器
-(void)animationTimerCallback:(NSTimer*)timer
,在你释放它之后…我明白了,我不知道如何阻止它发生。我调用stopAnimation命令,它进入该函数,它做的第一件事是点击invalidate,然后跳转到DeAlloc。当我调用stopAnimation时,我的应用程序是否可以调用animationTimerCallback?虽然您应该始终通过access访问IVAR,但DeAlloc是一个大的例外。在dealloc中直接释放您的IVAR。也就是说,此错误表明您在dealloc开始时调用[super dealloc](必须在结束时调用),或者
self
已过度释放。