Delayed call, with possibility of cancelation? - objective-c

How do I trigger a delay, let's say I want to call a method (once) in 3 seconds from now, and how do I cancel that call if I need to?

You can also use -[NSObject performSelector:awithObject:afterDelay:], and +[NSObject cancelPreviousPerformRequestsWithTarget:selector:object].

Use NSTimer. Use this to set up a call to method in three seconds time. It will only be called once:
[NSTimer scheduledTimerWithTimeInterval: 3
target: self
selector: #selector(method:)
userInfo: nil
repeats: NO];
method needs to look like this:
- (void) method: (NSTimer*) theTimer;
You can pass parameters into the method using userInfo (set to nil in the above example). It can be accessed in the method as [theTimer userInfo].
Use the invalidate method on NSTimer to cancel it.

in your header..
NSTimer *timer;
when you want to setup..
timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(yourMethod:) userInfo:nil repeats:NO];
when you want to cancel..
[timer invalidate];

Related

Xcode - NSTimer firing at random intervals? No consistency

So I am using NSTimer to run a function every minute, it fires at the correct time for the first 3 or so attempts and then it suddenly starts firing every second. I have no idea why this is happening? Would anyone be able to let me know as to why NSTimer is firing inconsistently?
Here is the line where I have declared my timer.
[NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:#selector(checkForLocation) userInfo:nil repeats:YES];
It is worth noting that I have NSTimer declared inside of viewDidAppear.
Any help is appreciated,
Thank you.
Try to create a instance for NSTimer by declaring a property. Write a function which will initialize the timer and don’t forget to invalidate it before re-intializing it. Call initializeMyTimer in your -viewDidAppear.
-(void) initializeMyTimer
{
if(myTimer)
{
[myTimer invalidate];
myTimer = nil;
}
myTimer = [NSTimer scheduledTimerWithTimeInterval:60.0f
target:self
selector:#selector(checkForLocation)
userInfo:nil
repeats:YES];
}

Start & Stop Timer

I have a timer that calls a function every 10 seconds:
[NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:#selector(checkForMessages)
userInfo:nil
repeats:YES];
It calls the function:
- (void)checkForMessages
{
//do something here
}
Two questions:
How do I stop the timer if needed?
Can I put this timer and function somewhere so that I can call it from different view controllers?
"scheduledTimerWithTimeInterval" returns an "NSTimer" object.
If you hold onto that object (e.g. set and get it via a "property"), you can stop it via the NSTimer invalidate method.
And since you're asking for code, add this to your view controller's .h #interface:
#property (strong) NSTimer * messageTimer;
Then, in your view controller's .m file:
self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:#selector(checkForMessages)
userInfo:nil
repeats:YES];
Makes sense?

Fire IBAction automatically

I have a button and want to fire it automatically by itself without touch.
Is it possible?
-(IBAction)xxx:(id)sender
My answer assumes you have the method:
- (IBAction)someAction:(UIButton *)sender {
}
and that you have a reference to the button in an instance variable named someButton.
If you just need to "fire it" now, simply call it:
[self someAction:someButton];
If you need to "fire it" once, but later, you can do:
// call it 5 seconds from now
[self performSelector:#selector(someAction:) withObject:someButton afterDelay:5.0];
If you want to fire it repeatedly, use a timer:
myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(buttonTimerFired) userInfo:nil repeats:YES];
- (void)buttonTimerFired {
[self someAction:someButton];
}
Action can be called like every regular function - you can do it by running a timer on something else.
You should use NSTimer for doing your work.
[NSTimer scheduledTimerWithTimeInterval: 0.01f target: self selector: #selector(BtoonMethod) userInfo: nil repeats: NO];
-(void)BtoonMethod
{
// write code for call yor button method
}

NSTimer doesn't call method

I'm really frustrated now, googled the whole internet, stumbled through SO and still didn't find a solution.
I'm trying to implement an NSTimer, but the method which I defined doesn't get called. (seconds are set correctly, checked it with breakpoints). Here is the code:
- (void) setTimerForAlarm:(Alarm *)alarm {
NSTimeInterval seconds = [[alarm alarmDate] timeIntervalSinceNow];
theTimer = [NSTimer timerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
}
- (void) showAlarm:(Alarm *)alarm {
NSLog(#"Alarm: %#", [alarm alarmText]);
}
The object "theTimer" is deined with #property:
#interface FooAppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> {
#private
NSTimer *theTimer;
}
#property (nonatomic, retain) NSTimer *theTimer;
- (void) setTimerForAlarm:(Alarm *)alarm;
- (void) showAlarm:(Alarm *)alarm;
What am I doing wrong?
timerWithTimeInterval simply creates a timer, but doesn't add it to any run loops for execution. Try
self.theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
instead.
Also don't forget to check if
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
target:(id)target
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats
is called in the main thread.
You've created an NSTimer object but you haven't scheduled it to be run. timerWithTimeInterval:target:selector:userInfo:repeats: creates a timer that you can schedule to run later, for example, to create a timer at application launch and have it start counting when the user presses a button. Either call
[[NSRunLoop currentRunLoop] addTimer:theTimer forMode:NSDefaultRunLoopMode]
at the end of setTimerForAlarm or replace
theTimer = [NSTimer timerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
with
theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
which creates a timer and immediately schedules it.
Well you may want to actually schedule your NSTimer on the run loop :) instead of timerWithTimeInterval use scheduledTimerWithTimeInterval.
theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
While all of the answers are right, there is an even simpler solution that doesn't involve a NSTimer at all. Your setTimerForAlarm: implementation can be reduced to one simple line:
[self performSelector:#selector(showAlarm:) withObject:alarm afterDelay:[[alarm alarmDate] timeIntervalSinceNow]]

Cocoa Touch - Timers

How can I make a timer that counts down from 3 and then runs a method? How would I do that?
Is that different from a timer counting from 0 to 3? It will still wait three seconds, either way.
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(myMethod:) userInfo:nil repeats:NO];
Better way might be to use performSelector:withObject:afterDelay: method:
[self performSelector:#selector(myMethod) withObject:nil afterDelay:3.0f];
Or in case method takes 1 parameter:
[self performSelector:#selector(myMethod:) withObject:parameter afterDelay:3.0f];
If method takes multiple parameters you'll need to use NSInvocation class
- (void) handleTimer: (NSTimer *) timer
{
do some work here...
} // handleTimer
// at some point in your controller
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 3.0
target: self
selector: #selector(handleTimer:)
userInfo: nil
repeats: NO];