Re: NSTimer and user interface events
Re: NSTimer and user interface events
- Subject: Re: NSTimer and user interface events
- From: Chris Kane <email@hidden>
- Date: Fri, 16 Jan 2004 13:19:33 -0800
On Jan 12, 2004, at 8:37 AM, Shawn Erickson wrote:
On Jan 12, 2004, at 8:12 AM, Shoaib wrote:
I have an NSTimer that fires every 5 seconds and updates a data
structure in my application. The same data structure can also be
updated through a user interface event (like the user editing the
data).
My question is the following:
Do I need to protect my data structure from simultaneous updates from
the timer and user interface events?
Short answer: No, unless you have created secondary threads.
To elaborate: No, unless you're scheduling the timer on thread which
isn't the main thread, or accessing the data at other times, from other
threads.
Even if there are background threads, if the timer is scheduled on the
main thread and executed with the other UI things as Shawn described,
they aren't happening simultaneously.
The enhanced longer answer is that even in that case (or, even with
just one thread), you can run into "recursive" access to your data from
your timer firing function/method, which is distinct from the kind of
simultaneous access one gets from multi-threading/tasking. This is
intermediate to advanced stuff/situations I'm talking about here,
generally not stuff the documentation tries to explain to beginners.
If you do something in the method which the timer calls when it fires
which causes the run loop to be run in a nested activation, that could
trigger something which causes you to access the data again, while it
is still logically being accessed by the higher stack frame which is
the original timer firing. This is one of the reasons that run loop
stuff can be so complex at times. For example, a pseudo-stacktrace:
main()
bunch of stack frames here which are AppKit/run loop/whatever
the call to your NSTimer's action method here (ZZZ)
some other method
some other method which runs the run loop (AAA)
run loop stack frames
sources can get invoked here, like a timer
Suppose that the run loop is directly or indirectly run by some method
that your timer method calls, which is allowed (it is very desirable in
some situations). Well, the run loop is going to wait on its sources
again, and fire any that become ready. If you had a timer with a short
interval, the timer might even become ready while the run loop was
running recursively at point AAA above, and fire your method again,
while the previous activation of your method was still sitting higher
up on the stack (ZZZ) waiting for the method it called to return. If
ZZZ has half-changed the data structures, recursive invocations can
find it in an inconsistent state.
Now, that _particular_ example can't actually happen, because timers
refuse to fire again while they are still "firing", so they can't fire
"recursively"; that's because they keep track of what state they're in
and take special action to prevent recursion on the same timer. So,
for a SINGLE timer that can't happen -- but that's a simpler example to
understand than some of the situations that can actually occur!
If you simply protect your data with a mutex lock, it is conceivable
that you might run into deadlock in this kind of situation as well
(say, two timers you've created, which both want to access the same
data).
Generally, people don't do all the Right Things and get away with a
lot, but occasionally you might get bitten, so it's something to keep
in mind.
Chris Kane
Cocoa Frameworks, Apple
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.