NSNotification的一些小知识

栏目: IOS · 发布时间: 6年前

内容简介:notification即通知,当我们在不同类之间通信时就要用到通知方法。使用notification,我们能够把消息发送给多个监听该消息的对象,而不需要知道监听该消息对象的任何信息。消息的发送者将消息发送给通知中心,接受消息者也只需要向通知中心注册自己感兴趣的消息即可。这样就降低了消息的发送者和接收者之间的耦合。发送方将消息以NSNotification的形式发送给通知中心,然后通知中心将消息派发给注册了该消息的接收方。

notification即通知,当我们在不同类之间通信时就要用到通知方法。

使用notification,我们能够把消息发送给多个监听该消息的对象,而不需要知道监听该消息对象的任何信息。消息的发送者将消息发送给通知中心,接受消息者也只需要向通知中心注册自己感兴趣的消息即可。这样就降低了消息的发送者和接收者之间的耦合。

NSNotification

发送方将消息以NSNotification的形式发送给通知中心,然后通知中心将消息派发给注册了该消息的接收方。

@property (readonly, copy) NSString *name;@property (nullable, readonly, retain) id object;@property (nullable, readonly, copy) NSDictionary *userInfo;
  • name:通知的名字,一般为字符串。

  • object:通知携带的对象,一般为发送消息的对象本身。

  • userInfo:发送方在发送消息的同时想要传递的参数。

    创建一个notification有下列实例方法:

- (instancetype)initWithName:(NSNotificationName)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo

类方法:

+ (instancetype)notificationWithName:(NSNotificationName)aName object:(nullable id)anObject;
+ (instancetype)notificationWithName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;

发送通知

发送通知的方法主要有下列几种:

- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject;
- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;

注册监听者

注册监听者有下列几个方法:

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject;
- (id )addObserverForName:(nullable NSString *)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block;

很多人不明白这里的object指的是什么,在发送通知的时候也会传递一个object参数,一般情况下发送通知的object参数传递的是发送方自己,那么在注册监听者这里,object参数指代的也是发送方的这个object参数,意思就是接收object对象发出的名为name的通知,如果有其它发送方发出同样name的通知,是不会接收到通知的。如果把name和object这两个参数同时置为nil,则会接收所有的通知。这个可以自行测试。

  • 在注册监听者的时候,大家用的最多的是第一种方式。第二种方式对于大家来说比较陌生,这里多了一个参数queue和一个block,block即受到通知时执行的回调,参数queue指定了这个block在哪个线程中执行,如果block传的是nil,则表示这个回调block在发送通知的线程中执行,也即同步执行。

移除监听者

- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject;

在iOS9以后已经不需要手动移除监听者。

NSNotificationQueue(通知队列)

  • NSNotificationQueue是notification Center的缓冲池。

    如果我们使用普通的 - (void)postNotification:(NSNotification *)notification 这种方法来发送通知,那么这个通知就会直接发送到notification Center,notification Center则会直接将其发送给注册了该通知的观察者。但是如果我们使用NSNotificationQueue就不一样了,通知不是直接发送给notification Center,而是先发送给NSNotificationQueue,然后由NSNotificationQueue决定在当前runloop结束或者空闲的时候转发给notification Center,再由notification转发给注册的观察者。通过NSNotificationQueue,可以

    合并重复的通知,以便只发送一个通知。

  • NSNotificationQueue遵循FIFO的顺序,当一个通知移动到NSNotificationQueue的最前面,它就被发送给notification Center,然后notification Center再将通知转发给注册了该通知的监听者。

  • 每一个线程都有一个默认的NSNotificationQueue,这个NSNotificationQueue和通知中心联系在一起。当然我们也可以自己创建NSNotificationQueue,可以为一个线程创建多个NSNotificationQueue。

    NSNotificationQueue的核心方法有下列几个:

//类方法返回当前线程的默认的NSNotificationQueue。defaultQueue
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray *)modes;

上面这个方法是使用NSNotificationQueue来发送通知用的。这里面有四个参数。

  • notification是所要发送的通知。

  • postingStyle 这是一个枚举类型的参数。

typedef NS_ENUM(NSUInteger, NSPostingStyle) {    NSPostWhenIdle = 1,    NSPostASAP = 2,    NSPostNow = 3};

NSPostingStyle即指发送通知的方式,一共有三种方式。

  1. NSPostWhenIdle

    通过字面意思大概可以知道是在空闲时发送。

    简单地说就是当本线程的runloop空闲时即发送通知到通知中心。

  2. NSPostASAP

    ASAP即as soon as possible,就是说尽可能快。

    当当前通知或者timer的回调执行完毕时发送通知到通知中心。

  3. NSPostNow

    多个相同的通知合并之后马上发送。

  • coalesceMask

    coalesceMask即多个通知的合并方式。它也是一个枚举类型。

    有时候会在一段时间内向NSNotificationQueue发送多个通知,有些通知是重复的,我们并不希望这些通知全部发送带通知中心,那么就可以使用这个枚举类型的参数。

typedef NS_OPTIONS(NSUInteger, NSNotificationCoalescing) {    NSNotificationNoCoalescing = 0,    NSNotificationCoalescingOnName = 1,    NSNotificationCoalescingOnSender = 2};
  1. NSNotificationNoCoalescing

    不管是否重复,不合并。

  2. NSNotificationCoalescingOnName

    按照通知的名字,如果名字重复,则移除重复的。

  3. NSNotificationCoalescingOnSender

    按照发送方,如果多个通知的发送方是一样的,则只保留一个。

  • modes

    这里的mode指定的是当前的runloop的mode,指定mode后,只有当前线程的runloop在这个特定的mode下才能将通知发送到通知中心。

同步与异步发送

  • 同步发送通知

    当我们使用下列这些方法时是使用的同步发送通知,这些也是我们平时常用的发送通知的方法。

- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject;
- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;

同步指的是,当发送方发送通知后,必须要等到所有的监听者完成监听回调,发送方才会接着执行下面的代码。所以如果监听者的回调有大量的计算要处理的话,发送方会一直等待,只有回调全部结束才接着往下执行。

  • 异步发送通知

    当我们使用NSNotificationQueue(通知队列)的下列方法发送通知时是异步发送通知:

- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle;
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray *)modes;

异步发送通知即只要发送方的通知发送出去了,不管监听方的回调是否执行完毕,反正我就开始执行下面的代码。

但是!!!需要注意的是,当NSPostingStyle的类型是NSPostWhenIdle和NSPostASAP时确实是异步的,而当类型是NSPostNow时则是同步的。


以上所述就是小编给大家介绍的《NSNotification的一些小知识》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Text Processing in Python

Text Processing in Python

David Mertz / Addison-Wesley Professional / 2003-6-12 / USD 54.99

Text Processing in Python describes techniques for manipulation of text using the Python programming language. At the broadest level, text processing is simply taking textual information and doing som......一起来看看 《Text Processing in Python》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具