NSTimer Not Stopping When Invalidated

nstimer, objective-c

Solution

You need to call `[self.messageTimer invalidate]` on the same thread on which you created the timer. Just make sure that the timer is created and invalidated on main thread.

dispatch_async(dispatch_get_main_queue(), ^{
    if ([UserType isEqualToString:@"Owner"]) {
        [self.messageTimer invalidate];
        self.messageTimer = nil;
    } else {
        self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                             target:self
                                                           selector:@selector(checkForMessages)
                                                           userInfo:nil
                                                            repeats:YES];
    }
});

Problem

I have the following code in my .h file: ``` #import <UIKit/UIKit.h> #import <CoreLocation/CoreLocation.h> #import <AVFoundation/AVFoundation.h> #import <MapKit/MapKit.h> @interface LandingController : UIViewController<CLLocationManagerDelegate> { CLLocationManager *LocationManager; AVAudioPlayer *audioPlayer; } @property (nonatomic, retain) NSTimer *messageTimer; - (IBAction)LoginButton:(id)sender; @end ``` I have the following code in my .m file: ``` @interface LandingController () @end @implementation LandingController @synthesize messageTimer; - (void)checkForMessages { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"BINGO:" message:@"Bingo This Works" delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil]; [alert show]; } - (IBAction)LoginButton:(id)sender { if ([UserType isEqualToString:@"Owner"]) { if (messageTimer){ [self.messageTimer invalidate]; self.messageTimer = nil; } } else { if (!messageTimer){ self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(checkForMessages) userInfo:nil repeats:YES]; } } } @end ``` But my timer doesn't want to stop when I call the invalidate. The LoginButton is only pressed twice, once when the strResult is = to "Guard" and then the application changes it to be equal to "Owner" and the user presses the login button again, so I don't think I'm setting multiple timers. After pressing the login button and starting the timer I segue to another view and then segue back to press the login button once more which is when I want the timer to stop. Do I need to do anything special to get the messageTimer since I switched views for a moment and then came back? Any ideas? Thanks!

Original source