Question

I try to show/hide view by tap using nstimer.

    @interface
        @property (nonatomic, retain)NSTimer *timer;
        UIView *view;
        @implementation
        view.hiden=YES;
        - (void)handleTap:(UITapGestureRecognizer *)sender{
        if([timer isValid)]{
timer.invalidate;///that gives me _EXC_BAD_ACCESS
}
        view.hiden=NO;
        timer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                     target:self
                                                   selector:@selector(targetMethod)
                                                   userInfo:nil
                                                    repeats:NO];


        }
        -(void)targetMethod{
        view.hiden=YES;
        }

If you understand something of this code, you can see the problem. If I tap once and wait 3 seconds, everthing is fine.But if I tap on it and tap again after 1.5 seconds, it should make another timer case and hide it after 3 seconds, but it hide it after 1.5 seconds, because old one is firing.

As you can see, I tried to invaliditate it but gives me error.

So how can I destroy it in proper way?

Était-ce utile?

La solution

Like this:

- (void)timerFired:(id)sender {
    _timer = nil;
    // do thing here
}

- (IBAction)handleTap:(id)sender {
    [_timer invalidate];
    _timer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                              target:self
                                            selector:@selector(timerFired:)
                                            userInfo:nil
                                             repeats:NO];
}

- (void)dealloc {
    [_timer invalidate];
}

There's a few key things you need to do here:

  • In the code that handles the firing of the timer, set the instance variable to nil.
  • Invalidate the old timer before creating the new one.
  • Don't worry about checking the timer's validity before invalidating it. If you follow this technique, the timer will either be valid or nil. It's perfectly safe to call invalidate on nil.
  • You don't have to nil _timer between invalidating it and reassigning it; this code is all on the main thread. If you were just cancelling the timer, though, you would.
    • The reason for this is that this timer has been scheduled on the runloop. That guarantees it won't fire until the next iteration of the runloop. The runloop will not iterate until you return.
  • In dealloc, you should invalidate the timer. (It might be more appropriate for you to do this in viewDidDisppear:; if you do, make sure you nil it after.)

Autres conseils

Use

[timer invalidate];

NSTimer

//before firing a timer null it always
[timer invalidate];
timer=nil;

//now create a new instance of it
timer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                     target:self
                                                   selector:@selector(targetMethod)
                                                   userInfo:nil
                                                    repeats:NO];

After you invalidate the timer, set the property to nil so that the next time you come thru it, you're not pointlessly holding onto an invalidated timer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top