iOS学习之NSNotificationCenter
>什么是NSNotificationCenter?
**可以这样说:说的不负责任点、可以认为所有的商用App,都会使用到监听者模式。NSNotificationCenter就是Apple提供的这种设计模式的封装。它简化了开发者自己重复造轮子的过程,节约时间的同时,提供了近乎完美的API,让开发者很方便的开发出一款App。**
<!--more-->
先说监听者模式的好处:
目前我在iOS中的使用NSNotificationCenter的地方,主要是在iOS获取服务器数据后,更新界面时候用到的。举个栗子:用户向服务器发出请求,修改了用户昵称。此时App就要把本地所有使用到用户昵称的界面都要更新显示成新设置的昵称。这个时候,使用监听者模式就非常酷了。只要在修改昵称后,发出一个通知(postNotification),让所有相关界面把用户昵称都更新成最新的就行了。
上面栗子中使用到了NSNotificationCenter的一个优势是:随意自由的跨域修改我想改的地方。比如从A界面发了一个通知,可以更新B、C、D界面,甚至可以更新跟A隔了几个域的S界面都可以。
需要使用到NSNotificationCenter的时候,注册通知(Name:vTagNotify)、写好selector回调方法。
需要发送通知的时候,一句话postNotification(Name:vTagNotify),就可以调用selector中的方法更新界面了。
NSNotificationCenter的用途可不光光是我上面说的更新界面这一个功能。它可以广播通知所有对象做一件事,也可以让感兴趣的对象去关注感兴趣的事。什么时候用到监听者模式,自己也可以思量一下。超实用的一种设计模式:D
废话说了这么多,可以上代码了。
注册通知:
{% highlight HTML %}
{
//注册监听者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(helloNotify:) name:@"vTagNotify" object:nil];
//执行函数
-(void)helloNotify:(NSNotification *)notification{
//name是vTagNotify
NSLog(@"notification: %@",notification.name);
//object是下文发送通知的TestClass对象
NSLog(@"notification: %@",notification.object);
//此处可以做事(更新界面等等)
}
}
{% endhighlight %}
对上面addObserver方法的参数说明:
* self:监听的持有者
* selector:监听的回调执行方法
* name:定义了消息名称
* object:只对post发送了object类型的消息感兴趣,并回调selector。当nil时,对所有发送的消息感兴趣。可以结合下文发送通知的object对应理解。
-----------------------
发送通知的第一种方法:
{% highlight HTML %}
{
NSNotification *_notify = [NSNotification notificationWithName:@"vTagNotify" object:[TestClass sharedTestClass]];
[[NSNotificationCenter defaultCenter]postNotification:_notify];
}
{% endhighlight %}
发送通知的第二种方法:
{% highlight HTML %}
{
[[NSNotificationCenter defaultCenter]postNotificationName:@"vTagNotify" object:[TestClass sharedTestClass]];
}
{% endhighlight %}
上面两种写法,仔细一看,其实就是分开写,与合起来写的区别。
发送通知的代码参数解释:
* name:标示通知,相当于当前发送的是什么通知。(比如更新昵称的通知,更新用户头像的通知等等,我此处用的是:kTagNotify来标示)
* object: 发送通知中的object,可以传递到selector中。但前提是:注册通知时的object必须与此处post出去的object是一致的。(我的测试:注册通知的时候,object等于一个字符串@"notify",发送通知的时候,object也只能是@"notify"才能触发selector回调。如果是发送通知的object是@"notify01"这样的串,都是无法对接回调selector的。)
------------------
然后是NSNotificationCenter中使用到了userinfo(用来传递值给相关的selector去处理。比设计模式中的最简单观察者更高级了一层。赞一个!)。如何使用、以及功能。看具体代码很明朗:
{% highlight HTML %}
{
//注册监听者
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(refreshList:) name:@"vTagRefreshList" object:nil];
//执行函数selector
-(void) refreshList:(id)sender{
//可以通过sender获取到name、object字段
NSNotification *notify = (NSNotification *)sender;
//notify.name notify.object
//可以通过userinfo获取字典数据
NSString *postType = [[sender userInfo] objectForKey:@"postType"];
//拿到了数据postType,就可以根据这个数据更新界面等等
}
//封装了dictionary的userinfo数据
NSDictionary *notify_dict = [NSDictionary dictionaryWithObject:self.postType forKey:@"postType"];
//把这个字典数据作为参数,通过发送通知发出去
[[NSNotificationCenter defaultCenter]postNotificationName:@"vTagRefreshList" object:nil userInfo:notify_dict];
}
{% endhighlight %}
说的很明朗啦~~~用起来也更顺手了。