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