Nsdistributednotificationcenter of OSX interprocess communication

Source: Internet
Author: User
Tags notification center

Part of the content is transferred from: HTTP://WWW.JIANSHU.COM/P/2503E3E5FC64

First, Nsnotificationcenter (Notification center)

Notification hubs are the key to the entire notification mechanism, which manages the listener's registration and logoff, the sending and receiving of notifications. The Notification Center maintains a sub-publication of the notification and 通知发送者 forwards all notifications sent to the corresponding listener. There are 2 notification hubs in cocoa, one is NSNotificationCenter that it can only handle notifications within one program, and the other is NSDistributedNotificationCenter (only on Mas OS), which can handle notifications between different programs on a single machine.

Nsdistributednotificationcenter

Each task has a default distributed notification center that you can access by using NSDistributedNotificationCenter the defaultCenter class method. This distributed Notification Center is responsible for handling notifications between the same machine's non-communicating tasks. If you need to implement inter-task communication on different machines, use distributed objects.

Sending distributed advertisements is an expensive operation. The notification is sent to a system-level server and then distributed to the task that contains the object that registered the distributed advertisement. The delay between sending announcements and advertising to another task is significant. In fact, if you make too many announcements, the queues that are filled with the server can be discarded.

Distributed announcements are distributed through the run cycle of tasks. Tasks must run in a "common" mode of a run cycle, such as a NSDefaultRunLoopMode pattern, to receive distributed advertisements. If the task receiving the advertisement is multithreaded, do not assume that the notification will reach the main thread. Announcements are usually distributed to the running loops of the main thread, but other threads can also receive advertisements.

Although the regular notification center allows any object to be advertised (that is, to advertise the encapsulated object), the distributed Notification Center supports only the NSString object being advertised as its advertisement object. Because the advertised object and the advertised observer may be in different tasks, the advertisement cannot contain pointers to arbitrary objects. Therefore, distributed notification hubs require advertisements to use strings as advertised objects. The advertised match is based on this string, not on the object pointer.

1, Application 1: When received "Piaoyun Notification" notice, will issue "ShowWindow Notification" notice

1- (void) Callbackwithnotification: (Nsnotification *) mynotification;2 {3     if([Mynotification.name isequaltostring:@"Piaoyun Notification"]){4NSString *observedobject =@"com.chinapyg.notification";5Nsdistributednotificationcenter *center =6 [Nsdistributednotificationcenter Defaultcenter];7[Center Postnotificationname:@"ShowWindow Notification"8                               Object: Observedobject9Userinfo:nil/*No dictionary*/Ten Deliverimmediately:no]; One     } ANSLog (@"Notification Received"); - } -  the- (void) Applicationdidfinishlaunching: (Nsnotification *) anotification { -NSString *observedobject =@"com.chinapyg.notification"; -     //handle notifications between different processes on a single computer -Nsdistributednotificationcenter *center = + [Nsdistributednotificationcenter Defaultcenter]; - [Center Addobserver:self + selector: @selector (callbackwithnotification:) AName:nil/*@ "Piaoyun Notification"*/ at                  Object: Observedobject]; -}
- (void) Callbackwithnotification: (Nsnotification *) mynotification; {    if([Mynotification.name isequaltostring:@"ShowWindow Notification"]) {Dispatch_async (Dispatch_get_main_queue (),^{Self.testwindowcontroller= [[Testwindowcontroller alloc]initwithwindownibname:@"Testwindowcontroller"];        [Self.testwindowcontroller showwindow:self];    }); } NSLog (@"Notification Received1");}- (void) Applicationdidfinishlaunching: (Nsnotification *) anotification {[Self.window close]; Nsdistributednotificationcenter*center =[Nsdistributednotificationcenter Defaultcenter]; NSString*observedobject =@"com.chinapyg.notification"; [Center addobserver:self selector: @selector (callbackwithnotification:) Name:nil/*@ "Piaoyun Notification"*/                 Object: Observedobject]; NSLog (@"Notification Send"); [Center Postnotificationname:@"Piaoyun Notification"                          Object: Observedobject userinfo:nil/*No dictionary*/Deliverimmediately:no]; }

2, the application 2 runs up, first sends "Piaoyun Notification" the notice, when receives "ShowWindow Notification" The time, displays the window.

Second, nsnotificationqueue (notification queue)

The notification queue, as the name implies, is the queue that puts notifications (notification objects). The general way of sending notifications, notification center received by the sender of the notification, will be distributed to listeners immediately, but if the notification in the notification queue, the notification can wait until some specific time to issue, such as wait until the previous notification in Runloop processing, or runloop idle time. It is like a buffer pool in the notification center, which sends out notifications in the notification queue.


These notifications that are stored in the notification queue are issued in a FIFO manner, where a notification arrives at the head of the queue, which is forwarded to the notification hub by the notification queue, and the notification Center is then distributed to the appropriate listeners.

Each thread has a default notification queue, which is associated with the notification hub, and you can create multiple notification queues for threads or notification hubs yourself.

The notification queue provides 2 important features to the notification mechanism: notification merging and asynchronous sending of notifications

Notification Merge

Sometimes, you want to send a notification to a certain object to do something for an event that might happen more than once, but when the event recurs, you don't want to send the same notification again.

You might do this by setting a flag to decide if you still need to send a notification, when the first notification is sent out, set the flag to not send notifications, then when the same event occurs again, it will not send the same notification, looks good, but this is not to achieve our purpose, Still the problem, because the normal notification mode is synchronized by default, the sender of the notification needs to wait until all listeners receive and process the message to proceed with the next business logic, that is, when the first notification is issued, may not be back, the second notification has been sent out, When you change the value of flag, you may have sent a number of notifications ...

This time, you need to use the Notification Queue notification merge feature. Using NSNotificationQueue the enqueueNotification:postingStyle:coalesceMask:forModes: method, set the value of the third parameter coalescemask to specify a different merge rule, Coalescemask has 3 given values:

NS_OPTIONS(NSUInteger, NSNotificationCoalescing) {    NSNotificationNoCoalescing = 0,    NSNotificationCoalescingOnName = 1, NSNotificationCoalescingOnSender = 2};

are not merged, merged by the name of the notification, and merged by the sender of the notification.

After you set up the merge rule and then add it to the notification queue, the notification queue looks in the previous queued notification according to the given consolidation rule, and then removes the notification that conforms to the merge rule, thus achieving the purpose of sending only one notification.

Merge rules can also use | symbolic joins to specify multiple:

NSNotification *myNotification = [NSNotification notificationWithName:@"MyNotificationName" object:nil];[[NSNotificationQueue defaultQueue] enqueueNotification:myNotification postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender forModes:nil];
Send Notifications asynchronously

Using the following 2 methods of the notification queue to add a notification to the notification queue, you can send a notification asynchronously to the current thread, which returns immediately after the call is received and processed by all listeners who are not waiting for the notification.

- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle;- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray<NSString *> *)modes;

Note: If the queued thread is notified that the notification queue has ended before it is sent to the notification hub, the notification will not be sent.

Notice that in the second method above, there is a modes parameter that, when a specific runloop mode is specified, the notification value will be emitted only if the current runloop is the specified mode.

Notification queue send notification there are 3 types, which are the parameters in the above method postingStyle , and it has 3 values:

NS_ENUM(NSUInteger, NSPostingStyle) {    NSPostWhenIdle = 1,    NSPostASAP = 2, NSPostNow = 3};
  • NSPOSTASAP (send Posting as Soon as Possible as soon as possible)
    Notifications that enter the queue in NSPOSTASAP style are sent to the notification hub when the current iteration of the run loop is complete, if the current run cycle mode matches the requested pattern (if the requested pattern differs from the current mode, the notification is emitted when the requested mode is entered). Because the run loop may make multiple call branches (callout) during each iteration, the notification may or may not be distributed when the current call branch exits and the control returns to the run loop. Other invocation branches may occur first, such as timers or events triggered by other sources, or other asynchronous notifications are distributed.

    Developers can often use the NSPOSTASAP style for expensive resources, such as displaying servers. It is expensive to flush the contents of the buffer to the display server after each draw, if there is a lot of customer code in the window buffer that is being painted during a call to the branch that runs the loop. In this case, each draw ... method queues a notification such as "Flushtheserver" and specifies merging by name and object, as well as using the NSPOSTASAP style. As a result, only one of those notifications is distributed at the end of the run cycle, and the window buffers are only refreshed once.

  • Nspostwhenidle (send when idle)

    Notifications that enter the queue in Nspostwhenidle style are emitted only when the running loop is in the waiting state. In this state, there are no events in the input channel that runs the loop, including timers and asynchronous events. A typical example of entering a queue in nspostwhenidle style is when the user types text, and the other part of the program needs to display the length of the text byte. The cost of updating the size of the text input box after the user has entered each character is significant (and not particularly useful), especially when the user enters it quickly. In this case, cocoa will queue up notifications such as "Changethedisplayedsize" after each character type, while opening the merge switch and using the Nspostwhenidle style. When the user stops typing, only one "changethedisplayedsize" notification in the queue (due to the reason of the merge) is emitted when the running loop enters the wait state, and the display is therefore refreshed. Note that the running loop is about to exit (this happens when all the input channels are obsolete) and therefore no notification is made.

  • Nspostnow (send Now)

    Notifications that enter the queue in Nspostnow style are immediately sent to the notification hub after merging. Developers can use the Nspostnow style (or send via Nsnotificationcenter's postnotification: method) When they do not need to invoke the behavior asynchronously. In many programming environments, we not only allow synchronous behavior, but also want to use this behavior: that is, the developer wants the notification center to return after the notification is distributed in order to determine that the Observer object is notified and processed. Of course, when developers want to remove similar notifications from a queue by merging, they should use enqueuenotification ... method, and use the Nspostnow style instead of using the Postnotification: method.

Send notification to the specified thread

The thread that notifies the hub for distributing notifications is typically the thread that notifies the issuer of the notification. But sometimes, you might want to decide on your own decision to notify the thread, rather than the notification center. For a chestnut, there is an object listener in the background thread in the main thread of the interface changes, such as a window close or a button click, when the notification is issued in the main thread, usually can only be accepted in the main thread, but you will want this object can be in the background thread to receive notifications, Rather than the main thread. Then you need to grab them in the thread where the notifications were supposed to be, and then redirect them to the thread you want to specify.

One way to do this is to implement a custom notification queue (not NSNotificationQueue ) to save those notifications, and then redirect them to the thread you specify, and the approximate process is to use an object to listen to a notification as usual, and when the notification is triggered, the listener accepts it and then determines whether the current thread is the correct thread to process the notification. , if it is processed, otherwise, save the notification to our custom notification queue and send a signal to the target queue indicating that the notification needs to be processed in the target queue, the target queue receives the signal, and the notification is removed from the notification queue and processed.

Nsdistributednotificationcenter of OSX interprocess communication

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.