how can i stop NSTimer in runTime?
I am using the following code .but NSTimer runs again and again.(i want to repeat NStimer, i want to stop in runtime )
- (void)TimerCallback
{
.....
[self.tim invalidate];
self.tim = nil;
}
-(void)timerStart
{
self.tim = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(TimerCallback) userInfo:nil repeats:YES];
}
It's repeats:NO if you want it to run only once. You have repeats:YES.
It is [tim invalidate] and not self.tim invalidate
Do not do self.tim = nil, because that is releasing it. invalidate does everything.
For the record, make sure your property is all correct, ie
#property (nonatomic, retain) NSTimer *happyTimer;
and
#synthesize happyTimer;
For the record, you must be on the same thread.
Hope it helps.
Here is all the lines of code cut from a working production example:
NSTimer *ttt;
#property (nonatomic, retain) NSTimer *ttt;
#synthesize ttt;
self.ttt = [NSTimer scheduledTimerWithTimeInterval:7.00
target:self selector:#selector(ringBell) userInfo:nil repeats:YES];
if ( [ttt isValid] )
[ttt invalidate];
[ttt release]; // in dealloc
You need to add some debugging lines NSLog(#"I just invalidated"); and so on, to make sure you don't have some basic mistake.
Your code seems correct. Usually this problem is starting twice the timer. You can try
-(void)timerStart {
[self.tim invalidate];
self.tim = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(TimerCallback) userInfo:nil repeats:YES];
}
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 am new to Iphone programming I want to know about how to create a NSTimer in Xcode Iphonesdk. Can anyone suggest me?
NSTimer *timer = [NSTimer scheduleTimerWithTimeInterval:TIME_INTERVAL target:self selector:#selector(YOUR_METHOD_NAME) userInfo:nil repeats:YES/NO];
Hope this will help you........
Here is a code to add NSTimer..
1) in .h file
NSTimer *timer;
2) in .m file
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(YOUR_METHOD_NAME) userInfo:nil repeats:YES];
Note:: so your method will continuously call after every 1 second.. and if you want to call the timer method only once set repeats:NO...
To Invalidate Timer
3) to invalidate the timer where you want..
[timer invalidate];
Following is my sample code.
#interface TrackTimer : NSObject {
NSTimer *timer;
}
#property (nonatomic, retain) NSTimer *timer;
- (void) startTimer;
- (void) stopTimer;
- (void) timerFired;
#end
TrackTimer.m
#synthesize timer;
- (void) startTimer
{
NSLog(#"Timer started ...");
if(timer)
{
timer = nil;
}
timer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:#selector(timerFired) userInfo:nil repeats:NO];
}
- (void) stopTimer
{
NSLog(#"Timer stoped ...");
[tTimer invalidate];
}
- (void) timerFired
{
NSLog(#"Timer Fired ... :)");
}
I have to use the same timer object from 3 different view controllers, my problem is startTimer method do not invoke timerFired method in 2nd UIViewController. Its works perfectly on 1st and 3rd View Controller.
appln Flow : 1stView -> 2ndView -> 3rdView
You are doing everything right... almost.
Your timer does not fire, because of the "if" statement.
if (timer) {
timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(boom) userInfo:nil repeats:NO];
}
Here, the "if" statement returns NO, because the timer is not yet initialized..
The fact that you make it a property and synthesize it does not mean that (timer != nil)
If you remove the "if" statement it should work...
From the Apple docs on NSTimer:
The message to send to target when the timer fires. The selector must have the following signature:
- (void)timerFireMethod:(NSTimer*)theTimer
So, it looks like the signature of your timerFired method needs to be expanded to include one parameter '(NSTimer*)theTimer' and your selector needs to be #selector(timerFired:)
Don't really know how you do that, but NStimer has a class method called
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats. So you can do it like this:
timer=[NSTimer scheduledTimerWithTimeInterval:2 target:self
selector:#selector(timerFired)
userInfo:nil
repeats:YES];
This will invoke the timerFired method for you.
P.S.Here's the link to a simple app that does just what you want.
http://www.mediafire.com/?8uz115drqzb2nan
This code works well
#property (nonatomic, retain) NSTimer *timer;
self.timer = [[NSTimer timerWithTimeInterval:kAdsAppearTimeInterval target:self selector:#selector(timerFired:) userInfo:nil repeats:NO] retain];
this code get CFRelease . But why? i use retain property
self.timer = [NSTimer timerWithTimeInterval:kAdsAppearTimeInterval target:self selector:#selector(timerFired:) userInfo:nil repeats:NO];
Not a lot to go on... but:
#property (nonatomic, retain) NSTimer *timer;
self.timer = [[NSTimer timerWithTimeInterval:kAdsAppearTimeInterval target:self selector:#selector(timerFired:) userInfo:nil repeats:NO] retain];
That'll end up retaining the timer 3 times and self once.
Timer +1 for -retain
Timer +1 for scheduling it
Timer +1 for the property assignment
self +1 for being the target of the timer
The timer will be released once when fired (because it'll be unscheduled from the run loop). self will be released when the timer is invalidated or released (you shouldn't have to care).
So, you have two retain counts to account for. The call to retain in the code above is noise; don't bother as the property assignment will retain it.
That leaves the property's retain. The most obvious way is to release the timer in -dealloc.
However, unless you need to potentially invalidate the timer before it fires, there is no reason to have an instance variable referring to the timer at all. Even if you do have an iVar, there is no reason to retain the timer either as long as you set self.timer = nil in your timerFired: method (and set it to nil if you invalidate anywhere).
For a non-repeating timer, if you need a reference to the instance variable, I would not recommend a retain property in its declaration to avoid confusion.
setting the instance variable (myTimer)
myTimer = [NSTimer scheduledTimerWithTimeInterval:myTimerInterval
target:self
selector:#selector(myTimerFired:)
userInfo:nil
repeats:NO];
when the timer fires, you can mark the instance variable as nil since its released when the timer is fired
- (void) myTimerFired: (NSTimer *) theTimer{
myTimer = nil;
//etc
}
This way if you have to reference your instance variable (for example to disable the timer when exiting a View controller)
-(void) onBack {
if(myTimer){
[myTimer invalidate];
myTimer = nil;
}
}
This is probably something I should know by now, I am creating an instance of NSTimer using the NSTimer class method. I am pretty sure the returned object is autoreleased, my question is in terms of memory management should I be then retaining and releasing the timer object (METHOD: 1), or simply just assigning it directly to the #property (METHOD: 2)(or should I be doing something totally different?)
// METHOD: 1
#property (nonatomic, retain) NSTimer *myTimer;
.
NSTimer *tempTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:#selector(executeOnTimer) userInfo:nil repeats:YES];
[self setMyTimer:tempTimer];
//[tempTimer release];
.
- (void)dealloc {
[pulseTimer release];
[super dealloc];
}
OR SIMPLY:
// METHOD: 2
myTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:#selector(executeOnTimer) userInfo:nil repeats:YES];
EDIT:
One final point, if I just write (see below) without assigning to a property is there any chance that the timer is going to get deallocated, basically does it stay around until the program exits. Just curious how its retained?
[NSTimer scheduledTimerWithTimeInterval:120.0 target:self selector:#selector(executeOnTimer) userInfo:nil repeats:YES];
In order to take ownership over the NSTimer you can do one of these with the same effect:
self.myTimer = [NSTimer scheduledTimerWithTimeInterval: ...]; // implicit setter
or
[self setMyTimer: [NSTimer scheduledTimerWithTimeInterval:...]]; // explicit setter
or
myTimer = [[NSTimer scheduledTimerWithTimeInterval: ...] retain];
or
self->myTimer = [[NSTimer scheduledTimerWithTimeInterval: ...] retain];
This is the good way:
self.myTimer = tempTimer;
// don't call [tempTimer release]
This will retain it automcailcally due to the property which retains it.
Just calling myTimer = … doesn't use the setter while self.myTimer = … does.