Re: Converting from Carbon Event Manager to NSTimer
Re: Converting from Carbon Event Manager to NSTimer
- Subject: Re: Converting from Carbon Event Manager to NSTimer
- From: Jason Coco <email@hidden>
- Date: Tue, 23 Sep 2008 23:17:02 -0400
On Sep 23, 2008, at 19:20 , Dan Birns wrote:
I'm trying to convert from Carbon to Cocoa for a number of reasons
which I won't go into here.
My application needs to set a timer that causes a function to be
called at a time in the future. This is non-repeating, and
sometimes has be immediate. I need it to be as efficient as
possible, because it's called frequently.
In Carbon I'm using:
EventLoopTimerUPP upp;
upp = NewEventLoopTimerUPP(macTimerCallback);
InstallEventLoopTimer(GetMainEventLoop(),0, kEventDurationForever,
upp,0,&macTimer);
Then, when I need to set the timer:
nextTimerTime = CFAbsoluteTimeGetCurrent() + nextTimer;
SetEventLoopTimerNextFireTime(macTimer, nextTimer);
In Cocoa, the system I'm using requires me to allocate a new NSTimer
every time I need to set a timer:
self.timer = [NSTimer scheduledTimerWithTimeInterval: t // seconds
target: self
selector: @selector (mainLoopTimer:)
userInfo: nil
repeats: NO];
In your example, what is the value of t? There is some time required
to set up the timer and get it scheduled, so you should take that into
account. Did you want
it to fire again at some point or did you want to schedule a new timer
in mainLoopTimer: ?
This is working fine, but our performance is poor. It's not so poor
that it's obviously broken, but I'm looking for ways to improve it.
I've been try to alloc one NSTimer that I reuse, and I've had no
success doing so.
I've tried
timer = [NSTimer alloc];
[timer initWithFireDate:[NSDate date] interval:t target:self
selector:@selector(mainLoopTimer:) userInfo:halTimer repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSDefaultRunLoopMode];
This has failed. Investigating, I called [timer isValid] and it
returns false. I've tried altering the args in various ways without
success. I've also had various problems retain'ing this timer.
When I add [timer retain];, it crashes having exhausted the stack,
where it's calling retain over and over.
That's because the timer fires NOW when done this way and interval is
ignored since repeats is NO. Once the timer fires it is invalidated
(again, since repeats is NO). To create a non-repeating timer that
fires in t seconds using the init method, try this:
timer = [[NSTimer alloc] initWithFireDate:[NSDate
dateWithTimeIntervalSinceNow:t] interval:0 target:self
selector:@selector(mainLoopTimer:) userInfo:halTimer repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSDefaultRunLoopMode];
What you might want to do is create a repeating timer which fires
every so often (whatever granularity you need). Then in the timer
function, if nextTimer's time hasn't yet been reached, return
immediately. If it has, do whatever you need to do and reset nextTimer
to some time in the future. That should be more efficient (or at least
get you better granularity after the initial firing of the timer). You
can also manually fire a repeating timer (without worrying about it
getting invalidated) if you want it to start AS SOON AS POSSIBLE
without waiting for it to get scheduled and fired from the run loop
(the initial firing can be a bit delayed in that case...)
Jason
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden