An object that manages an app’s main event loop and resources used by all of that app’s objects.
SDK
- macOS 10.0+
Framework
- App
Kit
Declaration
class NSApplication : NSResponder
Overview
Every app uses a single instance of NSApplication
to control the main event loop, keep track of the app’s windows and menus, distribute events to the appropriate objects (that’s, itself or one of its windows), set up autorelease pools, and receive notification of app-level events. An NSApplication
object has a delegate (an object that you assign) that’s notified when the app starts or terminates, is hidden or activated, should open a file selected by the user, and so forth. By setting the delegate and implementing the delegate methods, you customize the behavior of your app without having to subclass NSApplication
.In your app’s main()
function, create the NSApplication
instance by calling the shared
class method. After creating the application object, the main()
function should load your app’s main nib file and then start the event loop by sending the application object a run()
message. If you create an Application project in Xcode, this main()
function is created for you. The main()
function Xcode creates begins by calling a function named NSApplication
, which is functionally similar to the following:
void NSApplicationMain(int argc, char *argv[]) {
[NSApplication sharedApplication];
[NSBundle loadNibNamed:@"myMain" owner:NSApp];
[NSApp run];
}
The shared
class method initializes the display environment and connects your program to the window server and the display server. The NSApplication
object maintains a list of all the NSWindow
objects the app uses, so it can retrieve any of the app’s NSView
objects. The shared
method also initializes the global variable NSApp
, which you use to retrieve the NSApplication
instance. shared
only performs the initialization once. If you invoke it more than once, it returns the application object it created previously.
The shared NSApplication
object performs the important task of receiving events from the window server and distributing them to the proper NSResponder
objects. NSApp
translates an event into an NSEvent
object, then forwards the event object to the affected NSWindow
object. All keyboard and mouse events go directly to the NSWindow
object associated with the event. The only exception to this rule is if the Command key is pressed when a key-down event occurs; in this case, every NSWindow
object has an opportunity to respond to the event. When a window object receives an NSEvent
object from NSApp
, it distributes it to the objects in its view hierarchy.
NSApplication
is also responsible for dispatching certain Apple events received by the app. For example, macOS sends Apple events to your app at various times, such as when the app is launched or reopened. NSApplication
installs Apple event handlers to handle these events by sending a message to the appropriate object. You can also use the NSApple
class to register your own Apple event handlers. The application
method is generally the best place to do so. For more information on how events are handled and how you can modify the default behavior, including information on working with Apple events in scriptable apps, see How Cocoa Applications Handle Apple Events in Cocoa Scripting Guide.
The NSApplication
class sets up @autorelease
block during initialization and inside the event loop—specifically, within its initialization (or shared
) and run()
methods. Similarly, the methods AppKit adds to Bundle
employ @autorelease
blocks during the loading of nib files. These @autorelease
blocks aren’t accessible outside the scope of the respective NSApplication
and Bundle
methods. Typically, an app creates objects either while the event loop is running or by loading objects from nib files, so this lack of access usually isn’t a problem. However, if you do need to use Cocoa classes within the main()
function itself (other than to load nib files or to instantiate NSApplication
), you should create an @autorelease
block to contain the code using the classes.
The Delegate and Notifications
You can assign a delegate to your NSApplication
object. The delegate responds to certain messages on behalf of the object. Some of these messages, such as application(_:
, ask the delegate to perform an action. Another message, application
, lets the delegate determine whether the app should be allowed to quit. The NSApplication
class sends these messages directly to its delegate.
NSApplication
also posts notifications to the app’s default notification center. Any object may register to receive one or more of the notifications posted by NSApplication
by sending the message add
to the default notification center (an instance of the NSNotification
class). The delegate of NSApplication
is automatically registered to receive these notifications if it implements certain delegate methods. For example, NSApplication
posts notifications when it’s about to be done launching the app and when it’s done launching the app (will
and did
). The delegate has an opportunity to respond to these notifications by implementing the methods application
and application
. If the delegate wants to be informed of both events, it implements both methods. If it needs to know only when the app is finished launching, it implements only application
.
System Services
NSApplication
interacts with the system services architecture to provide services to your app through the Services menu.
Subclassing Notes
You rarely should find a real need to create a custom NSApplication
subclass. Unlike some object-oriented libraries, Cocoa doesn’t require you to subclass NSApplication
to customize app behavior. Instead it gives you many other ways to customize an app. This section discusses both some of the possible reasons to subclass NSApplication
and some of the reasons not to subclass NSApplication
.
To use a custom subclass of NSApplication
, send shared
to your subclass rather than directly to NSApplication
. If you create your app in Xcode, you can accomplish this by setting your custom app class to be the principal class. In Xcode, double-click the app target in the Groups and Files list to open the Info window for the target. Then display the Properties pane of the window and replace “NSApplication” in the Principal Class field with the name of your custom class. The NSApplication
function sends shared
to the principal class to obtain the global app instance (NSApp
)—which in this case will be an instance of your custom subclass of NSApplication
.
Important
Many AppKit classes rely on the NSApplication
class and may not work properly until this class is fully initialized. As a result, you should not, for example, attempt to invoke methods of other AppKit classes from an initialization method of an NSApplication
subclass.
Methods to Override
Generally, you subclass NSApplication
to provide your own special responses to messages that are routinely sent to the global app object (NSApp
). NSApplication
doesn’t have primitive methods in the sense of methods that you must override in your subclass. Here are four methods that are possible candidates for overriding:
Override
run()
if you want the app to manage the main event loop differently than it does by default. (This a critical and complex task, however, that you should only attempt with good reason).Override
send
if you want to change how events are dispatched or perform some special event processing.Event(_:) Override
request
if you want to modify how your app attracts the attention of the user (for example, offering an alternative to the bouncing app icon in the Dock).User Attention(_:) Override
target(for
to substitute another object for the target of an action message.Action:)
Special Considerations
The global app object uses @autorelease
blocks in its run()
method; if you override this method, you’ll need to create your own @autorelease
blocks.
Do not override shared
. The default implementation, which is essential to app behavior, is too complex to duplicate on your own.
Alternatives to Subclassing
NSApplication
defines numerous Delegation methods that offer opportunities for modifying specific aspects of app behavior. Instead of making a custom subclass of NSApplication
, your app delegate may be able to implement one or more of these methods to accomplish your design goals. In general, a better design than subclassing NSApplication
is to put the code that expresses your app’s special behavior into one or more custom objects called controllers. Methods defined in your controllers can be invoked from a small dispatcher object without being closely tied to the global app object.