iOS - NSTimer - 無効化後のSIGABRT - 今すぐ編集DeAlloc Msg

私は画像シーケンスを演奏するクラスにNSTimerを埋め込んでいます。基本的にUIImageViewをループして変更します。画像シーケンスを終了させるとすべてがうまくいくが、再生中にタイマーを止めようとすればそれは自分のものである。私はsigabrtを得る。編集:もはやsigabrtではなく、今DeAlloc私は説明することはできません。

フレームシーケンスの終わりの「停止」は、私が中期シーケンスを呼び出すのと同じ停止です。

だから、NSTimerが中途半端な機能やDeAllocを壊す原因になるかもしれません。私はそれを修正するために何を見ているかもしれませんポイントにもっと。

ありがとう。

I am using some example code from here: http://www.modejong.com/iOS/PNGAnimatorDemo.zip

Edit: I'll add what I believe to be the pertinent code here.

//このメソッドを呼び出してアニメーションを開始する

- (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];  
}

Edit2: So I commented out an NSAssert in DeAlloc, commenting that out shed a bit more light. Now getting to self.animationTimer = nil; and saying *** -ImageAnimator setAnimationTimer:]: Message sent to deallocated instance.

DeAllocは私がタイマーを無効にすると右に呼ばれているので、私はここでちょっと混乱しています。

0
あなたはそれを解放した後、おそらくタイマー - (void)animationTimerCallback:(NSTimer *)timer を呼び出しているでしょう...
追加された 著者 Gabriel,
うーん、DeAllocにNSAssertがありました...もう少し光を当てるとコメントしています...今は「self.animationTimer = nil;」になっています*** -ImageAnimator setAnimationTimer:]:解放されたインスタンスに送信されたメッセージ。 DeAllocは私がタイマーを無効にした直後に呼び出されています...だからここで少し混乱しています。
追加された 著者 Mytheral,
私はそれを得る、私は起こることからそれを保つ方法を理解していない。私はstopAnimationコマンドを呼び出し、それはその関数に入り、最初のことはヒットがinvalidateであり、次にDeAllocにジャンプして、私がstopAnimationを呼び出すときに私のアプリケーションがanimationTimerCallbackを呼び出すことができるのだろうか?
追加された 著者 Mytheral,
あなたがSIGABRTを取得しているなら、それは通常あなたが主張を打つことを意味します。あなたのログを見てアサーションが何であるかを見てください。
追加された 著者 Rob Napier,
あなたは常にあなたのivarsにアクセスする必要がありますが、deallocは大きな例外です。 deallocであなたのivarsを直接リリースしてください。つまり、このエラーは、あなたがdealloc(最初に呼び出さなければならない)の始めに[super dealloc]を呼び出しているか、または self が過剰にリリースされていることを示唆しています。
追加された 著者 Rob Napier,

2 答え

私は働いていますが、最適ではない解決策を持っています。

私はそれが最後のフレームにあるフレームを設定する別の関数を追加し、必要に応じてシーケンスを終了します。

しかし、中断してシーケンスを止めようとすると、なぜそれがクラッシュしているのかという問題は解決しません。

0
追加された

まあ、私はこのコードを書いたので、私はそれがうまく動作するはずです:)あなたはビューで完了する前にstopAnimatingを呼び出す必要があります、deallocでアサーションを得た唯一の方法は、ビューが割り当て解除された場合ですまだアニメーション化していました。それは起こるべきではありません、それはまさにそこにアサーションが存在する理由です。アサーションについて説明する大きなコメントもありますが、それについては不明な点がありますか?

- (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];

スーパービューからビューを削除する前に、すべてがうまくいくでしょう。

0
追加された