NSTimer doesn't get fired at specified date - objective-c

I'm creating an NSTimer:
NSTimer *saveProgressSizeTimer = [[NSTimer alloc]
initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:2.0f]
interval:1.0f
target:self
selector:#selector(myMethod:)
userInfo:myUserInfo
repeats:YES];
However, the timer doesn't get fired. The method doesn't get invoked.
If I print my date I get the following:
2012-10-12 15:19:02.786 MyApp[1768:303] fire date: 2012-10-12 13:21:02 +0000
Shouldn't it be "2012-10-12 15:21:02" ? Somehow the hours are wrong. But why? If I change the Time Zone from UTC/GMT +1 hour (I'm sitting in Germany) to another, the date is still 2012-10-12 13:19:02 plus two seconds.
What am I doing wrong?
Thanks!

A time created with initWithFireDate must be added to a run loop, e.g.
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
Use scheduledTimerWithTimeInterval to create a timer that is automatically scheduled on the current run loop.
PS: The description method of NSDate uses always GMT, that probably explains your output.

addTimerIf you create your timer like this:
NSTimer *saveProgressSizeTimer = [[NSTimer alloc]
initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:2.0f]
interval:1.0f
target:self
selector:#selector(myMethod:)
userInfo:myUserInfo
repeats:YES];
You must add the timer in the RunLoop like this:
[[NSRunLoop currentRunLoop] addTimer:saveProgressSizeTimer forMode:NSDefaultRunLoopMode];

Related

NSTimer - Why does scheduledTimerWithTimeInterval work, yet initWithFireDate doesn't?

This calls my selector repeatedly each 60 seconds as desired:
autoDeleteTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:[SimpleDB class] selector:#selector(autoDelete:) userInfo:nil repeats:YES];
This next line doesn't call it at all. Not initially nor after 60 seconds:
autoDeleteTimer = [[NSTimer alloc] initWithFireDate: [NSDate dateWithTimeIntervalSinceNow:1] interval:60 target:[SimpleDB class] selector:#selector(autoDelete:) userInfo:nil repeats:YES];
Can anyone explain why? Thanks.
You need to add the second timer to the main loop:
[[NSRunLoop mainRunLoop] addTimer: autoDeleteTimer forMode:NSDefaultRunLoopMode];
From the documentation of the method:
- (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
Return Value:
The receiver, initialized such that, when added to a run loop, it will
fire at date and then, if repeats is YES, every seconds after that.
You must add the new timer to a run loop, using addTimer:forMode:.
Upon firing, the timer sends the message aSelector to target. (If the
timer is configured to repeat, there is no need to subsequently re-add
the timer to the run loop.)
NSTimer Apple Doc

How execute function on fixed time on mac os x?

I write a simple application for mac osx that works with system time to calculate some data, i want to run an specific routine every time clock come to 12:00
Is there any system api for this?
How i do this?
actually i have a status bar item in my app that show current day in month in any selected calendar like gregorian and islamic, and i want to this value will be sync with system time
If your routine is the method - routine:(NSTimer *)timer of object:
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; // Current time
NSTimeInterval then = ((int)now + 86400) % 86400; // Next 12am
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:then];
NSTimer *timer = [[NSTimer alloc] initWithFireDate:date interval:86400 target:object #selector(routine:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

After initializing a timer other code never runs

Here is a code I use to init timer:
self.timer = [NSTimer scheduledTimerWithTimeInterval:5.0f
target:self selector:#selector(tick:) userInfo:nil repeats:YES];
NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
[currentRunLoop run];
int a = 10;
After calling "[currentRunLoop run];", "int a = 10;" doesn't perform.(even after calling tick: method by timer)
Why?
Thank you.
[Run loop run] stops there - it never goes past that line of code it just "loops"
You shouldn't need to create your own run loop usually.
If you want to achieve a timer on a separate thread just use a timer on the main thread and have the target method perform its work on a separate thread

addTimer: causing SIGABRT?

In xcode
timer = [NSTimer timerWithTimeInterval:auto_panic_upadte_secs
invocation:panicPendingTickInvocation repeats:FALSE];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
It gets past these lines of code, But as soon as I run it just SIGABRTs without/before my invocation happening.
Any idea to do this?
You may need to retain the arguments to your NSInvocation with the method
[panicPendingTickInvocation retainArguments];
To stop and autoreleased arguments from being released before you timer firers.

Objective C: App freezes when using a timer

It took me hours to figure out how to implement a timer into my program, but when it runs, the app doesn't load completely as it did before the timer.
In my main.m:
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
OutLauncher *theLauncher = [[OutLauncher alloc] init];
NSTimer *theTimer = [theLauncher getTimer];
[theTimer retain];
[[NSRunLoop currentRunLoop] addTimer: theTimer forMode: NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
[pool release];
return 0;
}
The file OutLauncher is being imported into that, which looks like this:
- (void)doStuff {
NSLog( #"Doing Stuff");
}
- (NSTimer *)getTimer{
NSTimer *theTimer;
theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector: #selector(doStuff) userInfo:nil repeats:YES];
return [theTimer autorelease];
}
The timer works, the console updates every second with the phrase "doing stuff" but the rest of the program just won't load. It will if I comment out the code I added to int main though
A few things:
You don't need to autorelease the timer you return after setting one up with [NSTimer scheduledTimerWithTimeInterval:] It is already autoreleased.
The timer created via scheduledTimerWithInterval is already added to the default run loop. So you don't need to use the following:
[[NSRunLoop currentRunLoop] addTimer: theTimer forMode: NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
In fact, you don't even need to keep a reference to the timer unless you need to cancel it yourself.
Here is what apple has to say about what you are doing in the documentation
run
Puts the receiver into a permanent
loop, during which time it processes
data from all attached input sources.
(void)run Discussion If no input sources or timers are attached to the
run loop, this method exits
immediately; otherwise, it runs the
receiver in the NSDefaultRunLoopMode
by repeatedly invoking
runMode:beforeDate:. In other words,
this method effectively begins an
infinite loop that processes data from
the run loop’s input sources and
timers.
Manually removing all known input
sources and timers from the run loop
is not a guarantee that the run loop
will exit. Mac OS X can install and
remove additional input sources as
needed to process requests targeted at
the receiver’s thread. Those sources
could therefore prevent the run loop
from exiting.
If you want the run loop to terminate,
you shouldn't use this method.
Instead, use one of the other run
methods and also check other arbitrary
conditions of your own, in a loop. A
simple example would be:
BOOL shouldKeepRunning = YES;
// global NSRunLoop *theRL =
[NSRunLoop currentRunLoop]; while
(shouldKeepRunning && [theRL
runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]]);
where shouldKeepRunning is set to NO
somewhere else in the program.
Availability Available in iOS 2.0 and
later.
So it looks like your code is doing what it is supposed to do. It is Logging all the timer events and waiting indefinitely for the run loop.
It looks like you're making it a lot more complicated than it needs to be. You don't need to put any code in your main.m file. If you want to fire the doStuff method every second, this is all the code you need:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector: #selector(doStuff) userInfo:nil repeats:YES];
You don't need to (auto)release it yourself. timer is already autoreleased. If you want to be able to cancel the timer, you will need to keep a reference of it. Then when you want to cancel, you just call invalidate and set the reference to nil.