iOS - NSTimer - SIGABRT na ongeldig maken - Nu bewerken DeAlloc Msg

Ik heb mijn NSTimer ingebed in een klasse die afbeeldingsreeksen afspeelt. In principe lus en verandert een UIImageView. Alles gaat goed als ik de afbeeldingsreeks laat eindigen, maar ... alleen als ik de timer probeer te stoppen terwijl deze wordt afgespeeld, krijg ik een signaal. Bewerken: geen sigabrt meer maar nu een DeAlloc die ik niet kan uitleggen.

De "stop" aan het einde van een framesequentie is dezelfde stop als in de middenreeks.

Dus wat kan ervoor zorgen dat een NSTimer de middenfunctie en DeAlloc verbreken. Meer naar het punt waarop ik zou kunnen kijken om het te repareren.

Bedankt.

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.

// Roep deze methode op om de animatie te starten

- (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 wordt gelijk gegeven als ik de timer ongeldig maak ... dus ik ben hier een beetje in de war.

0
Waarschijnlijk roep je de timer - (void) animationTimerCallback: (NSTimer *) timer nadat je hem hebt losgelaten ...
toegevoegd de auteur Gabriel, de bron
Hmmm er was een NSAssert in DeAlloc ... commentaar dat uit een beetje meer licht werpen ... Het gaat nu naar 'self.animationTimer = nihil;' en zeggen *** -ImageAnimator setAnimationTimer:]: bericht verzonden naar niet-toegewezen exemplaar. DeAlloc wordt gebeld nadat ik de timer heb gewist ... dus ik ben hier een beetje in de war.
toegevoegd de auteur Mytheral, de bron
Ik begrijp dat, ik begrijp niet hoe ik dat moet voorkomen. Ik roep de opdracht stopAnimation op en het komt in die functie terecht en het eerste dat het doet is hits invalidate en springt dan over naar DeAlloc. Kan mijn app animationTimerCallback aanroepen wanneer ik stopAnimation aan het bellen ben?
toegevoegd de auteur Mytheral, de bron
Als u SIGABRT krijgt, betekent dat meestal dat u een bewering treft. Kijk in je logs om te zien wat de bewering is.
toegevoegd de auteur Rob Napier, de bron
Hoewel je via toegang altijd toegang moet hebben tot je ivars, is dealloc de grote uitzondering. Laat je ivars rechtstreeks los in dealloc. Dat gezegd hebbende, suggereert deze fout dat je ofwel [super dealloc] aan het begin van je dealloc aanroept (deze moet aan het einde worden genoemd), of self is te snel vrijgegeven.
toegevoegd de auteur Rob Napier, de bron

2 antwoord

Ik heb een oplossing die werkt, maar niet optimaal is.

Ik heb zojuist een andere functie toegevoegd om het frame in te stellen op het laatste frame en het eindigt de reeks als ik nodig heb.

Maar het lost de vraag niet op waarom het crasht als ik probeer de reeks halverwege te stoppen.

0
toegevoegd

Welnu, ik heb deze code geschreven, dus ik kan je verzekeren dat het prima zou werken :) Je moet stopAnimating aanroepen voordat je klaar bent met het uitzicht, de enige manier waarop je zou kunnen beweren dat in dealloc is dat de weergave is verwijderd terwijl het nog steeds animeerde. Dat zou niet moeten gebeuren, en dat is precies waarom er een manier is om daar te beweren. Er is ook een grote opmerking over de bewering, wat is daar onduidelijk over?

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

Bel gewoon:

[view stopAnimating];

Voordat u de weergave uit de superview verwijdert, komt alles goed.

0
toegevoegd