Stopping a 'performSelector afterDelay' before it fires - iphone

I start a repeating NSTimer after a 4 second delay using the following code:
- (void)viewDidLoad {
[self performSelector:#selector(startTimer) withObject:self afterDelay:4];
}
- (void)startTimer {
NSTimer *mytimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(doSomething) userInfo:nil repeats:YES];
}
- (void)doSomething {
NSLog(#"What up!");
}
Problem is I may need to cancel startTimer from being called before the 4 seconds is up. Is there a way of doing this? I'd actually prefer to not use the performSelector in the first place (seems messy). If only NSTimer had something along the lines of this…
NSTimer *mytimer = [NSTimer
scheduledTimerWithTimeInterval:1.0
afterDelay:4.0 target:self
selector:#selector(doSomething)
userInfo:nil repeats:YES];
…then that would be perfect as I could just call the following:
[myTimer invalidate];
Any help or tips are much appreciated =)
P.S. I've found something called cancelPreviousPerformRequestsWithTarget in the NSObject class reference. Doesn't seem to be a method I can call from where this code runs however. If that's getting back on the right track your feedback is welcome!

Plz go through the SP post link
Stopping a performSelector: from being performed
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:#selector(sr)
object:nil];
The documentation for -performSelector:withObject:afterDelay: points you to the methods for canceling a queued perform request.

[myTimer invalidate] doesn't work?
Just keep a track of the object in your class, or in a centralized store for example.
If you do so, you could access your timer from everywhere you want, and invalidate it whenever it is needed

Use the NSTimer to fix issue.
self.autoTimer = [NSTimer timerWithTimeInterval:3.0 target:self
selector:#selector(connectionTimeout:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:autoTimer
forMode:NSDefaultRunLoopMode];
and call when you want to stop timer
[self.autoTimer invalidate];
self.autoTimer = nil;

Related

I want to invalidate all [self performSelector:#selector(showLyrics) withObject:nil afterDelay:2];

I am adding
[self performSelector:#selector(showLyrics) withObject:nil afterDelay:20];
but if user restart the song then the this selector should not get performed. So I just want to
know how I can cancel that. Because after 20 second it will get invoked but I don't want that, and reschedule
[self performSelector:#selector(showLyrics) withObject:nil afterDelay:20];
I'v so many
[self performSelector:#selector(showLyrics) withObject:nil afterDelay:2];
I want to cancel all those, which I've scheduled before.
[[NSRunLoop currentRunLoop] cancelPerformSelector:#selector(showLyrics)
target:self
argument:nil];
You can use NSTimer instead of performSelector:withObject:afterDelay:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:#selector(showLyrics) userInfo:nil repeats:NO];
To cancel:
[timer invalidate];
But you may want to invalidate before you start each time or keep timers in an array and iterate through them to cancel all of them.
Use an NSTimer and save a reference to it instead of performSelector. Afaik performSelector can't be cancelled. Edit: Apparently it can be cancelled, see omz's answer...
self.showLyricsTimer = [NSTimer scheduledTimerWithTimeInterval:20.0
target:self
selector:#selector(showLyrics)
userInfo:nil
repeats:NO];
To cancel the timer you use:
[self.showLyricsTimer invalidate];
But be careful to also invalidate the timer when your view disappears f.e. in the viewWillDisappear callback, since NSTimer retains it's target.
Cancels perform requests previously registered with performSelector:withObject:afterDelay:
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument
It seems this is what you are looking for or what you were looking for~~

NSTimer not stopping?

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..

How to create a NSTimer in Iphonesdk

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];

How to refresh webview every 5 seconds

How can I refresh or reload webview every 5 seconds?
You can use NSTimer to call the method every 5 seconds and use -reload method of UIWebview
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(updateWeb) userInfo:nil repeats:YES];
-(void)updateWeb
{
[webView reload];
}
you need to use `NSTimer`,
Check the below code as reference.
- (void) startTimer {
[NSTimer scheduledTimerWithInterval:5.0f target:self selector:#selector(showElapsedTime:) userInfo:nil repeats:YES];
}
showElapsedTime will be called after delay, you provide.
-(void) showElapsedTime: (NSTimer *) timer {
//Reload your webview here
[myWebView reload];
//you also need to invalidate your NSTimer for some condition
if(SomeCondition)
[timer invalidate]
}
Alternatively, I think you could also have the webview reload itself via javascript with the stringByEvaluatingJavaScriptFromString method. Something like this:
[webView stringByEvaluatingJavaScriptFromString:#"setTimeout('location.reload(true);',5000);"];
Not useful in all situations, but maybe in some.

Problem with NSTimer called inside my -parserDidEndDocument

I have a NSTimer object.
timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(timerAction) userInfo:nil repeats:YES];
[timer fire];
The method 'timerAction' repeats perfectly when call the timer from viewDidLoad method, but when I call the timer from parserDidEndDocument, the method 'timerAction' runs only once. Why is this?
you can try running the timer on the main thread.
Try this
create a new method that includes the code, to start timer, like :-
-(void)createTimer{
timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(timerAction) userInfo:nil repeats:YES];
[timer fire];
}
In Your parserDidEndDocument delegate, try this:
[self performSelectorOnMainThread:#selector(createTimer) withObject:[nil waitUntilDone:YES]