通知用起来说,还是蛮方便,蛮顺手的。有了通知,能够解决很多问题。NSNotification的使用可以分为三步走,或者四步走。
先说四步走
第一步:创建一个通知对象
+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject;
+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
一般来说,通过便利构造器创建也比较方便。
参考代码:
/**
*参数一:通知的名字
*参数二:通知的对象,没有指定就为nil即可
*参数三:通知的信息,是一个字典,可以传递对象等.不需要传递消息可以为nil,或者用第一个方法创建。
*/
NSNotification *notification = [NSNotification notificationWithName:@"notification" object:nil userInfo:@{@"":@""}];
第二步:注册一个通知
简单来说,就是用通知中心去添加一个通知观察者
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
添加观察者一定是通知中心去做的,通知中心不仅是添加观察者、还有发送通知、移除观察者也是通知中心去做的。
示例代码:
/**
*参数一:注册观察者对象,参数不能为空
*参数二:收到通知执行的方法,可以带参
*参数三:通知的名字
*参数四:收到指定对象的通知,没有指定具体对象就写nil
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reciveNotification:) name:@"notification" object:nil];
这还不算完,之前咱们说了,可以用通知传递消息,传递对象,那收到通知怎么传递的呢,这个得到收到通知执行的方法里面去看。上面有说,执行的方法可以带参,具体看代码。
- (void)reciveNotification:(NSNotification *)notification{
//这里就用一个字典接收,具体的值就可以通过字典的键值取出
NSDictionary *dic = notification.userInfo;
}
好了,现在就可以拿到参数了。如果不需要参数,那就更简单了,直接写一个不带参的方法就好了。
第三步:发送通知
- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
其实通知的步骤没什么严格的顺序,只要我发送通知的时候已有通知对象了,并且也有接收通知的对象了,那我就发呗。要是我发通知的时候没有接收通知的对象,那我发通知不是白发了么。一般来说,需要考虑一下观察者是否已经添加,观察者是否已经注销。
示例代码:
//这里发送的就是之前第一步创建的通知对象
[[NSNotificationCenter defaultCenter] postNotification:notification];
第四步:移除通知
- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;
当通知使用完之后,要移除通知。一般的,都习惯写在dealloc方法里面,或者viewController的viewdidDisappear方法里面。
示例代码
//这样写相当于移除了当前对象所有的观察者
[[NSNotificationCenter defaultCenter] removeObserver:self];
好了,到此四步走已经走完。其实三步走就是省略了第一步,利用NSNotificationCenter的后两个
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
发送方法也可以直接发送通知,省略第一步。个人习惯三步走了,简单明了不用创建对象。
再说说通知的其他地方。想必说道通知,消息,免不了会听说这么几个名词:单播、组播、广播
解释一下几个名词
单播:就好比打电话,我们一对一,我就跟你说。
组播:就好比聊天室,我们这聊天室的人都能听见,外面的听不见,我们闭上门开小组会。
广播:这就好比村头的大喇叭,我管你是谁,大喇叭一开,全都能听见。童鞋不要跟我犟,说大喇叭是针对一个村的,也是组播。大喇叭广播的时候有专门针对人分组么,我大喇叭再响一点,隔壁村也能听见。
好了,这几个名词解释完成之后再说说咱们的通知。
有注意到发送通知、接收通知、创建通知都有的那么几个参数么?NotificationName、object。当时就解释了,一个是通知的名字,一个是指定的对象。
那么这样我指定了接收通知的对象,是不是就只有这一个对象能收到消息;我指定了发送通知的对象,是不是只能收到这个对象的消息。那么这是不是就是一对一,这是不是单播呢?其实这里给混淆了一下,单播是指的发送方,与接收方无关,接收方指定了发送对象,就相当于单相思,我就听你的话,别人的不听。单播是指发送发指定了接收方,object有具体值,我就给你发,别人不发,这就是单播了。
再说说NotificationName,如果设置了这个,那么在接收方只要设置了相同的字段,那么就可以收到通知,若是object没有设置,那么可以看做就是组播了,不管那个对象设置了相同的字段就可以收到通知。
那么广播呢,这两个都不设置的话,既没有指定对象,也没有指定name,那么所有的对象都可以收到了,这就相当于广播。
对于组播和广播,也得看接收方收还是不收。你发出去了,我收着了,但不是我想要的,我一样不会去触发方法。如果接收方两个都没有设置,理论上就会受到所有的没有设置指定接收对象的消息,那么这样,之前说的组播又不对了。组播和广播,也得具体情况具体分析了,需要灵活运用。