简体   繁体   中英

NSTimer stops the first time I tell it to, then refuses to stop

I have declared an NSTimer in my UIViewController header as such:

NSTimer *mainTimer;

And I start it up in the viewWillAppear method in the implementation, so:

mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];

I have a button that flips the view over (standard utility app template) called showInfo and it has the command:

[mainTimer invalidate];

When my app launches, the timer starts and does it's thing. The first time I tap that button and the view flips, the timer stops. When I'm done with the flipSideViewController and the main view reappears, the timer starts again. So far, good. The problem is that subsequent button presses (and thus calls to [mainTimer invalidate] don't make the timer stop. It just keeps going. I can flip back and forth all I want and it continues to update. For grins, I put two invalidate calls in a row, but that crashes.

UPDATE:

Found the problem. Upon returning from the flipSideViewController , I was calling viewWillAppear myself, which would create the timer. The run loop also calls viewWillAppear automatically, so a second timer was created. This only happened after I had visited the flip side once so the timer (single instance) would stop normally when I flipped the first time. Odd that I can create two timers with the same name though...

Once a timer is invalidated, it will never fire again.

Thus, if the "timer keeps going", then it is a different timer. Make sure that you are speaking to the instances you think you are. I've seen quite a few bugs where developer alloc/init an instance and then load a NIB and cause a different instance of a particular class to come into play. I could see something similar happening here.

Note that it is impossible to invalidate a timer in the dealloc of the object that is the target of the timer. The timer will retain the target and, thus, the target cannot be [correctly] deallocated within the timer first being invalidated.

I just did exactly the same, and it seems to work for me. What I did in the xcode template:

Go to MainViewController.h and type:

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
    NSTimer* timer;
}

@property (nonatomic, retain) NSTimer* timer;

- (IBAction)showInfo:(id)sender;

@end

Go to MainViewController.m and add:

@synthesize timer;

-(void) viewWillAppear:(BOOL)animated {
    NSLog(@"Timer!");
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];
}

-(void) updateAll {
    NSLog(@"run");
}

- (IBAction)showInfo:(id)sender {    
    [timer invalidate];
    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
    controller.delegate = self;

    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];

    [controller release];
}

Just that, and it runs well for me. Does this help somehow? Maybe your problem is somewhere else - what do you do in updateAll ?

From the docs for [NSTimer invalidate] :

Stops the receiver from ever firing again and requests its removal from its run loop.

So I would call invalidate and then release your timer. It doesn't look like you're retaining on the timer in the first place. So, retain the timer when you make it, invalidate it when you want to, then release after the invalidate.

Next viewWillAppear, make sure you're making and retaining on a new timer.

It is possible viewWillAppear is called several times.

You should make sure the timer is invalidated before creating it

[mainTimer invalidate];
mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];

Of course, if you are also invalidating the timer on some other place, you should assign it to null.

[mainTimer invalidate];
mainTimer = NULL;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM