NSNotification order of observer notifications

2019-02-16 06:17发布

问题:

If I have several classes observing a particular NSNotification, in what order are the observers notified when the notification is posted?

回答1:

There is no guarantee as to what order notifications are sent out. If you need an ordering you may want to create a class that listens for one notification and sends out multiple ordered notifications that other classes can listen for instead.



回答2:

The order is undefined. Apple manages a list of observers and whenever the notification is posted, they iterate over the list and notify every registered observer. The list may be an array or a dictionary or something completely different (e.g. a linked list of structs) and since observers can be added and removed at runtime at any time, the list may also change at any time, thus even if you knew how the list is currently implemented, you can never rely on any specific order. Further any OS X update may cause the list internals to change and what holds true for 10.7 may not hold true for 10.8 or 10.6.



回答3:

I have tested it and it looks like the objects are ordered by addObserver method

Consol output for this test is :

2016-04-04 22:04:02.627 notificationsTest[1910:763733] controller 8
2016-04-04 22:04:02.629 notificationsTest[1910:763733] controller 1
2016-04-04 22:04:02.629 notificationsTest[1910:763733] controller 2

AppDelegate.m

#import "AppDelegate.h"

#import "ViewController.h"
#include <stdlib.h>


@interface AppDelegate ()

@property (strong, readwrite, nonatomic) NSTimer *timer;

@property (strong, readwrite, nonatomic) NSMutableArray *array;

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.array = [NSMutableArray array];

    ViewController *vc3 = [ViewController new]; vc3.index = 8;
    ViewController *vc1 = [ViewController new]; vc1.index = 1;
    ViewController *vc2 = [ViewController new]; vc2.index = 2;

    [self.array addObject:vc1];
    [self.array addObject:vc3];
    [self.array addObject:vc2];

    self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(sendNotification:) userInfo:nil repeats:YES];

    return YES;
}


- (void)sendNotification:(NSNotification *)notification {

    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationTitle1 object:nil];

}

@end

ViewController.m

#import "ViewController.h"

#import "AppDelegate.h"

@interface ViewController ()

@property (assign, readwrite, nonatomic) NSInteger index;

@end

@implementation ViewController

- (instancetype)init
{
    self = [super init];
    if (self) {

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondToNotification:) name:kNotificationTitle1 object:nil];

    }
    return self;
}

- (void)respondToNotification:(NSNotification *)notification {

    NSLog(@"controller %ld", self.index);

}

@end