iOS-NSNotificationCenter的应用

NSNotificationCenter提供了一种想程序中其他对象广播消息的机制(即一对多)。一个NSNotificationCenter对象本质上来说就是一张通知发送表。我们可以这样想象,有一张表,当我们在上面写下发生某件事时就通知某些人,那么当这件事真的发生时,我们就可以拿着这张表去挨个通知那些表上的人。这实际上就是观察者/订阅者模式的应用。

我们可以通过使用addObserver:selector:name:object:addObserverForName:object:queue:usingBlock:方法把某个对象注册到NSNotificationCenter对象中,以便能接收特定的通知消息(notifications)。一个对象可能会被注册为接受不同特定通知的观察者,即其可以接受多个通知且每个通知对应特定的selector进行通知的处理。
每个单独运行的Cocoa程序都有一个默认的通知中心(default notification center)。这个是单例实现的,我们不需要自己创建一个通知中心对象,只需要发送
defaultCenter消息就可以获取默认实例。注意!每个通知中心发送的通知只能通知给本程序中的对象,并不能通知别的应用程序中的对象。如果有需要则使用NSDistributedNotificationCenter。

下面是常用的一些方法介绍。

获取实例

//返回默认的notification center实例
+ defaultCenter

管理观察者

管理观察者就是注册观察者到通知中心或者移除对应的观察者。

注册观察者

注册观察这主要有两个方法,一个是注册观察者响应特定的seletor,一个则是以块结构方式注册观察者。

- (void)addObserver:(id)notificationObserver 
           selector:(SEL)notificationSelector 
               name:(NSString *)notificationName 
             object:(id)notificationSender

- (id<NSObject>)addObserverForName:(NSString *)name 
                            object:(id)obj 
                             queue:(NSOperationQueue *)queue 
                        usingBlock:(void (^)(NSNotification *note))block

我们来看一个官方小样例,这个是以块方式注册观察者的。

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
self.localeChangeObserver = [center addObserverForName:NSCurrentLocaleDidChangeNotification object:nil
    queue:mainQueue usingBlock:^(NSNotification *note) {

        NSLog(@"The user's locale changed to: %@", [[NSLocale currentLocale] localeIdentifier]);
    }];

删除观察者

移除观察者同样有两个方法。

//移除该对象上所有通知事件
- (void)removeObserver:(id)notificationObserver

//移除特定通知时间
- (void)removeObserver:(id)notificationObserver 
                  name:(NSString *)notificationName 
                object:(id)notificationSender

Post通知

当我们注册了之后,某个对象可能会发送某个通知给对应事件的观察者们。

- (void)postNotification:(NSNotification *)notification

- (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender

- (void)postNotificationName:(NSString *)notificationName object:(id)notificationSender userInfo:(NSDictionary *)userInfo

Demon

我们这里实现一个demon,这个demon有两个控制器。第一个控制器有一个文本显示域和一个按钮,点击按钮会跳转到第二个控制器。第二个显示器只有一个按钮用于返回第一个控制器。我们第一个控制器会注册自身为通知中心的观察者,第二个控制器返回时会向通知中心发送Post请求并传递一个参数,然后第一个控制器会收到通知并获取传递过来的参数显示出来。这样我们就达到通过通知中心传递数据的一个效果了。

第一个Controller:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //注册到通知中心
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateView:) name:@"LYSNotification" object:nil];
}

- (void)updateView:(NSNotification *)value
{
    NSString *str = [value object];
    self.textField.text = str;
}

- (IBAction)jumpToSecond:(id)sender
{
    [self presentViewController:[[SecondViewController alloc] init] animated:YES completion:nil];
}

第二个Controller:

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(20, 20, 100, 30)];
    self.view.backgroundColor = [UIColor whiteColor];

    [button setTitle:@"返回" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [button setBackgroundColor:[UIColor colorWithWhite:0.800 alpha:1.000]];
    [button addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:button];
}

- (void)back:(id)sender
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"LYSNotification" object:@"Hello World"];
    [self dismissViewControllerAnimated:YES completion:nil];
}

源代码

这里给出的是Github上的源码地址。
iOS-Demon——NSNotificationDemon

参考资料

iOS中Notification浅析