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
Related
I have the following UISearchbar code:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSTimer *myTimer;
NSLog(#"Timer=%#",myTimer);
if (myTimer)
{
if ([myTimer isValid])
{
[myTimer invalidate];
}
myTimer=nil;
}
myTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(OnTextChange) userInfo:nil repeats:NO];
}
after writing above code my log shows Timer=null,
OnTextChange is method which fetches data from Url.
Thanks in advance !!
Please write this line in .h file
NSTimer *myTimer;
and then do it in .m file
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSLog(#"Timer=%#",myTimer);
if (myTimer)
{
if ([myTimer isValid])
{
[myTimer invalidate];
}
myTimer=nil;
}
myTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(OnTextChange) userInfo:nil repeats:NO];
}
every time you are creating new object for NSTimer that's why it gives null.
declare NSTimer *myTimer globally.
You could use an NSTimer to delay the invocation of your search, and cancel the timer whenever the text changes: Give your object an NSTimer property or field; in searchBar:textDidChange: cancel any existing timer, then create and schedule a new one. The target of the timer should call your search method.
Refer this duplicate question: UISearchBar detect when user stop type and don't search immediately so detect pause
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 trying to create a framework for all of the custom objects and views that I have made and use often, by creating custom delegate classes and custom objects. Everything has gone well except when trying to get NSTimers to call the correct method inside of the delegate class.
Here is the basic setup.
-(void) startTimers {
NSTimer *timer1 = [NSTimer timerWithTimeInterval:5 target:self selector:#selector(doSomething:) userInfo:nil repeats:YES];
NSTimer *timer2 = [NSTimer timerWithTimeInterval:5 target:self selector:#selector(doSomethingElse:) userInfo:nil repeats:YES];
}
I can easily just call this method and whatever, but when this time fires it does not call the method I defined as the selector. I am pretty sure it has something to do with the delegate value and which class it is making as the delegate.
Note the file I am writing in is a subclass of UIView, which is set up to be a delegate using the #protocol tags and all of that.
What should I set as the target when defining my timers to get them to call the correct methods.
EDIT:
Here is an example of what I am doing:
ExampleView.h
#import <UIKit/UIKit.h>
#protocol ExampleViewDelegate;
#interface ExampleView : UIView {
NSTimer *timer;
}
-(void) initWithStuff:(id)stuff andFrame:(CGRect)frame;
-(void) testTimer;
#end
#protocol ExampleViewDelegate
-(void) someDelegateFunction;
#end
ExampleView.m
#import "ExampleView.h"
#implementation ExampleView
-(id) initWithStuff:(id)stuff andFrame:(CGRect)frame {
self = [super initWithFrame:frame];
timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:#selector(testTimer) userInfo:nil repeats:YES];
return self;
}
-(void) testTimer {
NSLog(#"Timer Fired");
}
#end
If you add this custom view into a viewcontroller it will never call that testTimer function and print "Timer Fired" So what I am thinking is that when I set the delegate for this timer, it is actually setting it to something else. Any ideas?
NSTimer *timer1 = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(doSomething:) userInfo:nil repeats:YES];
Notice the method is called "scheduledTimerWithTimeInterval"
I am making an iphone app and have scheduled an event called gameOver to occur after 15 seconds(when the game is over).
[self performSelector:#selector(gameOver) withObject:nil afterDelay:15.0];
How can I unschedule this event so that if someone wanted to press a reset button and start the game over, this scheduled event would be deleted and another one would be created.
I would use an NSTimer
with the retain-property NSTimer *myTimer
-(void) startTimer
{
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:myDelay target:self selector:#selector(myTimerExpiredMethod:) userInfo:nil repeats:NO];
}
-(void) myTimerExpiredMethod:(id)aSender
{
NSLog(#"timer expired");
self.myTimer = nil;
}
-(void) cancelTimer
{
[self.myTimer invalidate];
self.myTimer = nil;
}
Try
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget
aTarget would be the object the selector should be performed on. self in your example.
Edit:
This method is defined on NSObject so:
[NSObject cancelPreviousPerformRequestsWithTarget:myObject]
would be the syntax.
Edit 2:
Use
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument
to only unschedule calls to this specific selector.
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];
}