Objective C equivalent to javascripts setTimeout? - iphone

I was wondering whether there is a solution to raise an event once after 30 seconds or every 30 seconds in CocoaTouch ObjectiveC.

The performSelector: family has its limitations. Here is the closest setTimeout equivalent:
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 0.5);
dispatch_after(delay, dispatch_get_main_queue(), ^(void){
// do work in the UI thread here
});
EDIT:
A couple of projects that provide syntactic sugar and the ability to cancel execution (clearTimeout):
https://github.com/Spaceman-Labs/Dispatch-Cancel
https://gist.github.com/zwaldowski/955123

There are a number of options.
The quickest to use is in NSObject:
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
(There are a few others with slight variations.)
If you want more control or to be able to say send this message every thirty seconds you probably need NSTimer.

Take a look at the NSTimer class:
NSTimer *timer;
...
timer = [[NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:#selector(thisMethodGetsFiredOnceEveryThirtySeconds:) userInfo:nil repeats:YES] retain];
[timer fire];
Somewhere else you have the actual method that handles the event:
- (void) thisMethodGetsFiredOnceEveryThirtySeconds:(id)sender {
NSLog(#"fired!");
}

+[NSTimer scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:]
Documentation
You may also want to look at the other NSTimer methods

Related

How do I schedule a method to run after a delay

I want to be able to setup a timer to count for 23 seconds then perform a function. How could I do this? Would I need NSTimer?
Just use
[NSTimer scheduledTimerWithTimeInterval:23.0 target:self selector:#selector(myThingToDo) options:nil];
Typed on mobile, test first.
Also, there's a neat category available that allows you to use NSTimer with Blocks!
You could use GCD methods directly, which saves having to write a separate callback function:
// Just for clarity I'm defining the time period separately, 23 seconds from now.
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 23 * NSEC_PER_SEC);
dispatch_after(delay, dispatch_get_main_queue(), ^{
// Anything in here will be run on the main queue 23 seconds from now.
});

Issues with NSInvocation NSTimer and NSMethodSignature

I am trying to get a button to create a NSTimer which in turn will call a function (refreshView) to refresh UI elements, but I am having problems and I am not sure where the problem lies. Is the method signature wrong? Or am I getting the NSRunLoop part wrong? Or is it just horribly off base? Any help is appreciated.
-(IBAction)reload:(id)sender{
NSInvocation *displayInvocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:#selector(refreshView)]];
[displayInvocation setTarget:self];
NSTimer *slideShowTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
invocation:displayInvocation
repeats:YES];
[slideShowTimer fire];
NSRunLoop * a = [NSRunLoop currentRunLoop];
[a addTimer:slideShowTimer forMode:NSRunLoopCommonModes];}
-(void)refreshView{
[slideshow1 displayWithView:MajorImageView topicLabel:TopicLabel];
}
Your code seems very complicated for nothing. Do you want to (1) start a timer to call [refreshView] periodically, or (2) call it later.
For (1), simply setup a timer with,
[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
target:(id)target
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats]
No need to use a method invocation, a target/action will be enough
For (2), if you want to call it later,
[NSObject performSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInterval)delay]

call function after defined seconds without using timer

I am calling a function after 180 seconds using timer. But the timer sometimes behaves in different manner and calls the function multiple times in 180 seconds.
please suggest me how to call a function after each 180 seconds untill I post stop message without using timer.
Code
if(!tmr_CallWebService)
{
tmr_CallWebService = [NSTimer scheduledTimerWithTimeInterval:180 target:ClassTracing selector:#selector(startLocationTracing) userInfo:nil repeats:YES];
}
Thanks in advance
I think there is a method to do this task, here use it like this
[self performSelector:#selector(yourMethodName) withObject:[NSArray arrayWithObjects:firstArgument,secondeArgument,nil] afterDelay:180];
use nil in place of array if you have no argument in that method.
You can use - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay from NSObject

How can I trigger a method every 10 seconds without using NSTimer?

I would like to call a method every 10 seconds, but I want to use something other than NSTimer. What could I use to do this?
I know you said you didn't want to use timers, but just to make sure you know how simple it would be with a timer...
[NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:#selector(someMethod)
userInfo:nil
repeats:YES];
If you dont want to use the timer, you can use GCD which internally will make use of NSOperationQueue, nevertheless will work in all cases. For eg: i had a class which was inherited from NSOperation so the above methods didn't work so i had go go with GCD:
double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(popTime, queue, ^{
[self methodYouWantToCall];
});
The above code calls the method methodYouWantToCall after every three seconds.
You can create a loop with performSelector:withObject:afterDelay: setting afterDelay to 10.0.
I don't recommend this though, use an NSTimer.
- (void)callMeEvery10Seconds
{
[self performSelector:#selector(callMeEvery10Seconds)
withObject:nil
afterDelay:10.0];
// ... code comes here ...
}
If you are not using Cocos2D, you have to use a NSTimer to do this....
If you are using Cocos2D, use the schedule method
here's a link below that shows both :
How can I create a count down timer for cocos2d?
The easiest way to do so is:
- (void)scheduleLoopInSeconds:(NSTimeInterval)delayInSeconds
{
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(popTime, queue, ^{
[self callWhatEverMethodYouWant];
[self shceduleLoopcaInSeconds:delayInSeconds];//set next iteration
});
}
// now whenever you like call this, and it will be triggering "callWhatEverMethodYouWant" every 10 secs.
[self shceduleLoopcaInSeconds:10.0];

I should able to delay 2 seconds using NSTimer. How to do it?

I want to produce a delay of 2 seconds using NSTimer how to initialize timer in program?
Multiple options here.
If you just want a delay of 2 seconds you could use the sleep() function
#include<unistd.h>
...
sleep(2);
Or you may be able to use NSTimer like so
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(fireMethod) userInfo:nil repeats:NO];
And in your class you would have a method defined as
-(void)fireMethod
{
//Do stuff
}
Here you go...
[NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:#selector(action)
userInfo:nil
repeats:NO];
Simple answer: [NSThread sleepForTimeInterval:10.0];
Note that you should not really be thinking about delays in an event driven UI/OS. You should thinking about tasks you want to do now, and tasks you want to do later, and code these subtasks and schedule them appropriately. e.g. instead of:
// code that will block the UI when done in the main thread
- (void) methodC {
doA();
delay(2);
doB();
}
you might want to have code that looks more like:
- (void) methodA {
doA();
return; // back to the run loop where other useful stuff might happen
}
- (void) methodB {
doB();
}
and you can then schedule methodB with an NSTimer at the end of methodA, an NSTimer started by whatever called methodA, or, the best option, by the asynchronous completion routine of something started by methodA.