Unable to invalidate (Stop) NSTimer [duplicate]

2019-05-18 16:57发布

问题:

Possible Duplicate:
NSTimer doesn't stop

I am using a NSTimer to update the value of a slider while a audio is playing.

 if (sliderUpdateTimer) {
    [sliderUpdateTimer invalidate];
    sliderUpdateTimer=nil;
}

sliderUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateSliderForAudio) userInfo:nil repeats:YES];

once the audio is finished playing i am invalidating the Timer in audioPlayer delegate method.

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog(@"audioPlayerDidFinishPlaying");
[player release];
audioPlayer=nil;

[sliderUpdateTimer invalidate];
[sliderUpdateTimer release];
sliderUpdateTimer=nil;

}

The delegate method is getting called but the timer is not stopping.... I have only once thread on which i am runing the timer. But still the timer does not stop.... Any help in this regard is welcome...

回答1:

First of all, you would be over releasing it and should receive EXC_BADACCESS (you're not retaining the timer when you set it, so you shouldn't release it either). Should only call:

[sliderUpdateTimer invalidate];
sliderUpdateTimer=nil;

Since you don't receive a crash, it seems sliderUpdateTimer is nil when calling audioPlayerDidFinishPlaying:. User NSLog or put a breakpoint to check if this is true. If this is the case, you're probably setting it to nil at some point, search for slideUpdateTimer and check where this might occur.



回答2:

Hey try this thing...

- (void)stopTimer{
    [sliderUpdateTimer invalidate];
    //don't release it. as it is autoreleased.
    //[sliderUpdateTimer release];
    sliderUpdateTimer=nil;
}


-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    NSLog(@"audioPlayerDidFinishPlaying");
    [player release];
    audioPlayer=nil;
    [self performSelectorOnMainThread:@selector(stopTimer) withObject:nil waitUntilDone:NO];
}

I know you have only single thread but there may be two different run loops



回答3:

Try after removing the below lines from 1st section of your code

if (sliderUpdateTimer){
    [sliderUpdateTimer invalidate];
    sliderUpdateTimer=nil;
}

Don't need to call release message on that sliderUpdateTimer object

Because you have created that object with pending autorelease message

Here no need to use these lines.

I hope this will work.