> I am getting the beachball of death when I try to run an action that takes
> over a few seconds to complete.  Given, the beachball goes away after the
> task is completed - But for lengthy tasks, why can't I just allow the user
> to go along with their work instead of having them wait with the beachball?
> Would this be a problem with memory management, or something else entirely?

Something else entirely.

User interface events (mouse clicks, typing, etc) are handled on the
main thread. If you start performing a long task on the main thread,
the main thread is blocked from reacting to any user events until this
lengthy-task is complete. In more technical terms, while this long
task is running, the main thread's run loop (the mechanism that helps
handle UI events) cannot perform another iteration until your
lengthy-function returns. (Note that the beachball appears when an
app's main thread is blocked, as you've seen.)

There are two ways I solve this problem: either create a separate
thread, or use a timer.

Creating a separate thread could be opening a can of worms, depending
on how complex your app is. When using threads in your app, you must
make sure that your threads communicate safely. If you choose to go
the thread route, research "thread safety". There's around a
bajillion+1 articles on the subject; of course, you should look for
thread-safety articles written for the context of OS X/Cocoa. Also
note that much of Cocoa is _not_ thread-safe, so the burden will often
be on you to ensure that you're not using certain Cocoa classes
incorrectly in regard to thread safety. (That is, using locks where
appropriate, and not using certain classes or methods if they don't
support multiple threads.) An excellent article on thread-safety and
Cocoa can be found here:
http://mikeash.com/?page=pyblog/friday-qa-2009-01-09.html

On the other hand, you could use a timer. The idea behind a timer is
you complete a small part of the task every time the timer fires,
until the task is complete. In some respects, using a timer can be
'cleaner' than creating a separate thread: since a timer runs in the
main thread, you don't have to worry about using locks everywhere. In
other respects, using a timer can be much less elegant: you'll have to
store the lenghty-task's state somewhere, so every time the timer
fires, it knows where it left off. This can lead to some confusing and
overall inelegant code, but sometimes can still be easier than
creating a separate thread and dealing with the caveats of
thread-safety. (And sometimes you simply can't use a separate thread,
if something you rely on doesn't play nice with threads.)

The route you choose really depends on how well your task can be
self-contained. For example, if I'm calculating pi to ten billion
digits, but want the UI to remain responsive, this is a perfect time
to use a separate thread. On the other hand, if a lengthy task
requires access to Cocoa classes that don't like threads (and the
lenghty-task can be broken up into smaller chunks) then a timer may be
a better choice.

Hope this helps,

David
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to