The Event Loop

Other than the Tiny.m program in Chapter 4, we have not written a main( ) function for any of our applications. That’s because the PB template that was used to create our Calculator application already contained a main( ) function.

Let’s again look at the main.m file, which contains the main( ) function used by our Calculator application:

#import <Cocoa/Cocoa.h>

int main(int argc, const char *argv[])
{
    return NSApplicationMain(argc, argv);
}

Well, that’s not terribly useful. All it does is run the NSApplicationMain( ) function! What’s going on here?

When NSApplicationMain( ) runs, it performs the following steps:

  1. Processes any command-line options

  2. Sends the [NSApplication sharedApplication] class (or factory) message, which creates the NSApplicaton object, initializes the display environment, connects the application to the Window Server, and creates an autorelease pool

  3. Determines the main nib of the application (from the application plist) and then loads this nib with the owner of NSApp, the newly created NSApplication object

  4. Sends the [NSApp run] message to start up the application’s main event loop

The last step is the most important for our current discussion; it starts off the main event loop, where much of the power of Cocoa is found.

The Main Event Loop

When the NSApplication object called NSApp receives the run message, it starts the object’s main event loop. The event loop is a section of code that reads events and performs appropriate functions for those events. This is the primary place where the NSApplication object receives events from the Window Server. The event loop runs until the NSApplication object gets sent a stop: or a terminate: message. A stop: message causes the run method to stop and returns control to the caller. A terminate: message causes the application to quit gracefully, without returning control to the caller.

The NSApplication main event loop program does the following:

  • If there is an event waiting, gets it and processes it.

  • If there is a timer pending, executes it.

  • If data is received at a watched Mach port, reads it and calls the appropriate function. (See the discussion of Mach in Chapter 9.)

  • If data is pending at a watched file descriptor, reads it and calls the appropriate function.

  • Repeats until a stop: message is received.

The most common way of breaking out of the NSApplication’s main event loop is by sending a terminate: message to NSApp. Here’s what happens when the terminate: message is received:

  • If the NSApp object has a delegate that implements the appShouldTerminate: method, the corresponding message is sent to the delegate.

  • If the delegate’s appShouldTerminate: message returns NSTerminateCancel or NSTerminateLater, the terminate: method is aborted, and the main event loop continues to run. (In the case of NSTerminateLater, a timer is set that will schedule another terminate: message to be sent later.)

  • Otherwise, the application is terminated with a call to exit( ).

The fact that Cocoa handles the main event loop for the programmer is one of the primary differences between programming in Cocoa and programming in many other window-based environments. Because Cocoa handles most events automatically, individual programmers are freed from this tedious task, which in turn makes programs behave in a more reliable and unified fashion.

Nevertheless, Cocoa does allow you to write your own event loop or take over the event loop while something out of the ordinary is happening. Typically, you would do this for a special purpose that isn’t handled well by the Application Kit. For example, IB uses its own event loop when you Control-drag a connection from one object to another; this special event loop exits when the mouse button is released.

You can use the NSApplication method nextEventMatchingMask:untilDate:inMode:dequeue: to construct your own event loop. This method returns the next event that matches a mask that you provide. The mask allows you, for example, to read a mouse-up event but ignore a periodic event or flags-changed event. These other events will be saved until the main application event loop is running again.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.52.124