I have a timer which will be initialized on viewDidLoad, and be released on viewDidUnload, but I found the viewDidUnload nerver be called and each time the view is presented to user the viewDidLoad is called, so I have many timers running simultaneously... which is not what I want.
I just want to stop&release the timer when user navigate away from this view, how can I do that?
Don't initialize it on view did load, instead initialize it in view will apper and stop it in view will dissapear, that way it will stop when you navigate away and restart once you come back to that view.
I had the exact same problem you are having. This is the code just in case you need it:
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSLog(#"View will appear");
myTimer = [NSTimer timerWithTimeInterval:5.0 target:self selector:#selector(pageCycler) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer: myTimer forMode: NSDefaultRunLoopMode];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(#"View will dissapear");
[myTimer invalidate];
myTimer=nil;
}
Related
I'm trying to to stop an NSTimer with the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
timer3 = [NSTimer timerWithTimeInterval:5.0 target:self selector:#selector(start) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer3 forMode:NSDefaultRunLoopMode];
}
-(void)invalidate
{
[timer3 invalidate];
timer3 = nil;
}
and I call -(void)invalidate from another class like this:
-(void)timer
{
ClassOfMyTimer *class = [[ClassOfMyTimer alloc] init];
[class invalidate];
}
but the timer doesn't stop. Does anyone know what I'm doing wrong?
You need to call your invalidate method on the same instance of your class that created the timer. In your timer method you create a new instance of your class which could have its own timer and invalidate that.
I'm kind of confused by what you're trying to do here, but I'd guess that you're not maintaining a reference to timer3.
Have you created a property in the .h file for the timer:
#property (strong) NSTimer *timer3;
And then added a synthesize statement in the .m file:
#synthesize timer3;
Then, in viewDidLoad:, you can maintain a reference to the timer you're creating via:
self.timer3 = [[[NSTimer timerWithTimeInterval:5.0 target:self selector:#selector(start) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.timer3 forMode:NSDefaultRunLoopMode];
And, to invalidate the timer later:
[self.timer3 invalidate]
self.timer3 = nil
On preview, Sven also has a valid solution to an issue that might be impacting you..
I have an NSTimer declared in my .h and in the viewDidLoad of the /m I have the code:
timer = [NSTimer scheduledTimerWithTimeInterval:kComplexTimer target:self selector:#selector (main) userInfo:nil repeats:YES];
I also have [timer release]; in my dealloc.
However when I exit the view and return to it, the timer has not in fact released, it has doubles in speed! How do I solve this & what am I doing wrong???
Thanks
you don't need to release it as you have not retained it - as a rule.
all you need to do is just call [timer invalidate]; which will stop your timer.
Nice Answer , but good to check whether the time is nil or not to avoid unwanted exception..
if( timer ! = nil )
{
[timer invalidate];
timer = nil;
}
Thank you...
[timer invalidate];
timer = nil;
The second line is important if you want to reset the NSTimer
You must not call release on a object that it not be created by "new", "alloc", "retain", "copy".
In this case, you had created a Timer by scheduledTimerWithTimeInterval method, So you must not call release method but call [timer invalidate] to stop the timer.
How to switch from view1 to view 2 without having any button pressed. In my views i have is uiimageview and uitextview
With the NSTimer i m trying to do this
in the viewdidload method by using the following code:
In the firstviewcontroller.h file
#interface FirstViewController : UIViewController
{
NSTimer *SwitchingTimer;
}
In the firstviewcontroller.m file
- (void)viewDidLoad
{
[super viewDidLoad];
SwitchingTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(SwitchView) userInfo:nil repeats:YES];
}
-(void)SwitchViews:(id)sender
In the secondviewcontroller.m file
-(void) SwitchView
{
SecondViewController *SecondView = [[SecondViewController alloc]
initWithNibName:#"SecondViewController" bundle:nil];
SecondView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:SecondView animated:YES];
[SwitchingTimer invalidate];
self.SwitchingTimer = nil;
}
but nothing is happening. Can someone please tell me what i m missing in my code. Will appreciate help.
Thanks in advance.
There are a few issues in your code that are worth mentioning though I am not sure if those will provide you a solution.
Why do you want to repeat the timer every 2 seconds. I think you just want to switch to next view only once and if so then dont repeat the timer. So no need to invalidate the timer.
Your code for the SwitchView method is leaking memory. Please make sure that the SecondView is released after presenting the modal view(in case you are not using ARC).
Please follow the standard naming conventions. For eg: methods and variables should start with lowercase.
Regarding your issue please make sure that the nib name is correct and you are getting a valid object for the second view controller. You can check by using NSLog. Also ensure that the method Switchview is called. Try putting a break point and verify that it is called.
Another Option
If you just want to switch the view only once you can go for another option which does not make use of the NSTimer. For this, you can use performSelector:withObject:afterDelay:. This is just another option for the scenario I mentioned above.
You need to add it to the run loop:
- (void)viewDidLoad
{
[super viewDidLoad];
SwitchingTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(SwitchView) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer: SwitchingTimer forMode:NSDefaultRunLoopMode];
}
Also, you could rename -(void)SwitchView to -(void)switchViewTimerDidFire:(NSTimer *)timer. From the Documentation:
[...] The selector must have the following signature:
- (void)timerFireMethod:(NSTimer*)theTimer
The timer passes itself as the argument to this method.
I have a timer that launches in viewDidLoad that looks like this
[NSTimer scheduledTimerWithTimeInterval:0.001f target:self selector:#selector(Dragon:) userInfo:nil repeats:YES];
I want to be able to change my Interval with a variable. However, any time I try to place a variable where the 0.001f is I get errors... any ideas?
I have an app that does exactly what you are asking. I allow the user to change the speed of the timer within the app so I need to make that speed a variable. Here's how I did it:
I create a timer property on my main view controller class.
I initialize the timer when the main view controller class loads.
Each time thereafter, I invalidate my timer and reset it when the value changes.
Some snippets from inside of my main view controller .m file:
//How often to switch views (float)
#define kInterval [[NSUserDefaults standardUserDefaults] integerForKey:#"interval"]
- (void) viewDidAppear:(BOOL)animated{
[self setTimer];
}
- (void) setTimer{
[self.timer invalidate];
[self setTimer: [NSTimer scheduledTimerWithTimeInterval:kInterval target:self selector:#selector(timerFired) userInfo:nil repeats:YES]];
}
Is the app returning from a background process? If so, you may need to re-set the timer. You might also want to peek at CADisplayLink: http://developer.apple.com/library/ios/#documentation/QuartzCore/Reference/CADisplayLink_ClassRef/Reference/Reference.html%23//apple_ref/doc/uid/TP40009031
#King Popsicle you can take help of this method
(void)applicationWillEnterForeground:(UIApplication *)application OR
(void)applicationDidBecomeActive:(UIApplication *)application
You can fix the things in this method regarding the timer values :)
I'm trying to invalidate a timer when my app goes into background. The timer gets invoked when you hit a button that starts the timer and is in the TimerController.m file. Here is how it gets invoked.
mytimer = [NSTimer timerWithTimeInterval:1 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];//Timer with interval of one second
[[NSRunLoop mainRunLoop] addTimer:mytimer forMode:NSDefaultRunLoopMode];
Now, I'd like to invalidate mytimer when the app goes into background, so I tried putting
[mytimer invalidate];
into the - (void)applicationDidEnterBackground:(UIApplication *)application method the apps delegate. But this won't work since it's undeclared in the delegate. I thought by including TimerController.h into the delegate, this would work, but it won't.
So, I clearly don't know what I'm doing here. Can you help? How do it get it so that mytimer is invalidated when the app goes into background?
There’s also a UIApplicationDidEnterBackgroundNotification notification posted when the application goes into background. You can subscribe for this notification in your controller and handle the transition there:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(goBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
// and later:
- (void) goBackground {
[timer invalidate], timer = nil;
}
if (timer) {
[timer invalidate];
timer = nil;
}
in applicationReEnteredForeground notification method will also work