iOS通知详解 不同线程发出通知的处理
通知的基础知识
每一个应用程序都有一个通知中心,专门负责协助不同 对象之间的消息通信。
任何一个对象都可以向通知中心发布通知,描述自己在做什么。其他感兴趣的对象可以申请在某个特定通知发布时(或在某个特定的对象发布通知时)收到这个通知。
/**************** Notifications ****************/
//一个通知一般包含三个属性:
@property (readonly, copy) NSString *name;//通知名称
@property (nullable, readonly, retain) id object;//通知发布者(是谁要发布通知)
//一些额外的信息(通知发布者传递给通知接收者的信息内容)
@property (nullable, readonly, copy) NSDictionary *userInfo;
//初始化一个通知:(NSNotification)对象
- (instancetype)initWithName:(NSNotificationName)name object:(nullable id)object userInfo:(nullable NSDictionary *)userInfo
+ (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject;
+ (instancetype)notificationWithName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
/**************** Notification Center ****************/
//发布通知方法(通知中心提供了相应的方法来帮助发布通知)
//1.发布一个notification通知,可在notification对象中设置通知的名称,通知发布者、额外的信息等
- (void)postNotification:(NSNotification *)notification;
//2.发布一个名称为aName的通知,anObject为这个通知的发布者
- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject;
//3.发布一个名称为aName的通知,anObject为这个通知的发布者,aUserInfo为额外信息(通知的内容)
- (void)postNotificationName:(NSString *)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
/// 监听通知方法
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
///使用block处理通知回调用
// The return value is retained by the system, and should be held onto by the caller in
// order to remove the observer with removeObserver: later, to stop observation.
//Name: 通知的名称
//object:谁发出的通知
//queue: 队列,决定 block 在哪个线程中执行, nil 在发布通知的线程中执行
//usingBlock: 只要监听到通知,就会执行这个 block
- (id <NSObject>)addObserverForName:(nullable NSNotificationName)name object:(nullable id)obj queue:(nullable NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
//移除观察者
- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(nullable NSNotificationName)aName object:(nullable id)anObject;
在通知中心注册过的对象,需要在该对象释放前移除监听。否则,当相应的通知再次出现时,通知中心仍然会向该监听器发送消息。因为相应的监听器对象已经被释放了,所以可能会导致应用闪退.
执行顺序:一定要先向通知中心注册通知监听器,也就是谁要监听谁发布的消息,然后再执行发布消息,不然会导致消息发出来了没人接收的情况
同步或异步
[NotificationCenter defaultCenter] postNotification]
,这种方式是同步的,并且在哪个线程发,就在哪个线程收。
由于消息收和发都在同一个线程中。所以,尽量在主线程中post,不然会引起不必要的麻烦,ui刷新问题,崩溃问题等等
参考文档
addObserver调用多次
addObserver如果添加多次,当post的时候,也会收到多次。类似这种:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"TestNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"TestNotification" object:nil];