views:

1322

answers:

3

When does OS X decide to give your app a spinning beach ball? What can you do when programming an application to avoid this?

+15  A: 

The window server will show the spinning wait cursor when the frontmost application, or the application that has a window under the mouse pointer, has not responded to events from the window server within a certain window of time.

To avoid the spinning wait cursor, an application needs to service events in a timely fashion. There's no way around this window server behavior, and for good reason: Applications on Mac OS X aren't ever supposed to be unresponsive to the user.

Chris Hanson
+6  A: 

Assuming your application has sufficient hardware resources (which won't always be the case in reality), there's really no reason your app should ever beachball. If it does, figure out what section of code is blocking the user interface (if it's non-intuitive Shark.app will come in handy) and move that to a background thread (or use another strategy to eliminate the pause). Fortunately Cocoa and Objective-C have pretty good tools for threading, see NSOperationQueue to start with. Apple also has a few good documents on performance tuning, see this question for relevent links.

Marc Charbonneau
+5  A: 

The reason is that your app is blocking the UI. As the other posters said, the window manager can notice that you haven't handled events in awhile and put up this UI.

Most likely you are doing some IO (such as reading or writing to the disk, or doing network requests) synchronously on the UI (default) thread. A good rule of thumb to keeping your app responsive (and thus avoiding the beachball) is to never do synchronous IO on the UI thread. You can either use asynchronous IO (APIs that take a callback, do work on a background thread, and then notify you on the UI thread when they are done), or else you can use a separate background thread to do the work.

If you aren't doing IO, then you are probably in some kind of long loop on the UI thread that is causing you to be unresponsive. In that case, either optimize or remove the loop, or move it to a background thread.

Aaron Boodman