Inherits From: NSObject
Conforms To: NSObject (NSObject)
Declared In: Foundation/NSNotificationQueue.h
NSNotificationQueue objects (or simply, notification queues) act as buffers for notifications centers (instances of NSNotificationCenter). A notification queue maintains notifications (instances of NSNotification) generally in a FIFO order (First In First Out). When a notification rises to the top of the queue, the queue posts it to the notification center, which in turn dispatches the notification to all objects registered as observers.
NSNotificationQueue contributes two important features to OpenStep's notification mechanism: asynchronous posting and the coalescing of notifications. With NSNotificationCenter's postNotification: and its variants, you can post a notification immediately to a notification center. However, the invocation of the method is synchronous: Before the posting object can resume its thread of execution, it must wait until the notification center dispatches the notification to all observers and returns. With NSNotificationQueue's enqueueNotification:postingStyle: and enqueueNotification:postingStyle:coalesceMask:forModes:, however, you can post a notification asynchronously by putting it on the queue. These methods immediately return to the invoking object after putting the notification in the queue.
Posting to a notification queue can occur in one of three different styles. The posting style is an argument to both enqueueNotification:... methods:
. NSPostWhenIdle. The notification is posted when the run loop is idle.
. NSPostASAP. The notification is posted as soon as possible.
. NSPostNow. The notification is posted immediately to the notification center.
Note: See Enqueuing with the Different Posting Styles, below, for details on and examples of enqueuing notifications with the three postingStyle: constants.
What is the difference between enqueuing notifications with NSPostNow and posting notifications (postNotification:)? Both post notifications immediately (but synchronously) to the notification center. The difference is that enqueueNotification:... (with NSPostNow as posting style) coalesces notifications in the queue before posting while postNotification: does not.
Coalescing is a process that removes notifications in the queue that are similar to the notification just enqueued (or posted, if posting style is NSPostNow. The notification queue scans the notifications in the queue for those with attributes matching the new notification and removes them, except for the notification that is topmost in the queue (closest to being posted). You indicate the criteria for similarity by specifying the NSNotificationCoalescing constants in the third argument of enqueueNotification:postingStyle:coalesceMask:forModes: (OR them in if multiple):
. NSNotificationNoCoalescing. Do not coalesce notifications in the queue.
. NSNotificationCoalescingOnName. Coalesce notifications with the same name.
. NSNotificationCoalescingOnSender. Coalesce notifications with the same sender.
Every task has a default notification queue, which is associated with the task's default notification center. You can create your own notification queues, and have multiple queues per center and task; but you can have only one notification center per task. NSNotificationQueue is a public, concrete class; instances of it are mutable.
Enqueuing with the Different Posting Styles
Any notification enqueued with the NSPostASAP posting style is posted to the notification center when the code executing in the current run loop callout completes. Callouts can be Application Kit event messages, file descriptor changes, timers, or another asynchronous notification. You'd typically use the NSPostASAP posting style for an expensive resource, like the Display PostScript server. When many clients draw on the window buffer during a callout, it's expensive to flush the buffer to the Display PostScript server after every draw operation. So in this case, each draw... method enqueues some notification such as FlushTheServer with coalescing on name and sender specified, and a posting style of NSPostASAP. As a result, only one of those notifications is dispatched at the end of the current callout, and the window buffer is flushed only once.
A notification enqueued with the NSPostIdle posting style is posted only when the run loop is in a wait state. In this state, there is nothing in the run loop's input channels, be it timers or other asynchronous notifications. A typical example of enqueuing with the NSPostIdle posting style occurs when the user types text, and the program displays the size of the text in bytes somewhere. It would be very expensive (and not very useful) to update the displayed size after each character the user types, especially if the user types fast. In this case, the program enqueues a notification after each character typed such as ChangeTheDisplayedSize with coalescing turned on and a posting style of NSPostWhenIdle. When the user stops typing, the single ChangeTheDisplayedSize notification in the queue (due to coalescing) is posted when the run loop is in a wait state and the display is updated.
A notification enqueued with NSPostNow is posted immediately to the notification center. You enqueue a notification with NSPostNow (or post one with NSNotificationCenter's postNotification:) when you do not require asynchronous calling behavior. For many programming situations, synchronous behavior is not only allowable but desirable; you want the notification center to return after dispatching so you can be sure that observing objects have received the notification. Of course, you should enqueue with NSPostNow rather than use postNotification: when there are similar notifications in the queue that you want to remove through coalescing.
Creating Notification Queues