iOS 中通知機(jī)制詳解
NSNotification 通知的對象,一條通知就是一個NSNotification對象,包含如下屬性:
@property (readonly, copy) NSNotificationName name;
@property (nullable, readonly, retain) id object;
@property (nullable, readonly, copy) NSDictionary *userInfo;
NSNotificationCenter 管理通知的類,負(fù)責(zé)添加,發(fā)送,移除通知
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject;
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
關(guān)于name和object
- name為空,接收所有通知
- name不空,添加通知的object空,仍然接收所有name相同的通知
- name不空,添加通知object不空,接收name和object都匹配的通知
- 發(fā)送通知的時候,是否指定object對接收者不影響
- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(nullable NSNotificationName)aName object:(nullable id)anObject;
移除通知,iOS8之前需要手動移除通知,iOS8之后系統(tǒng)會在dealloc調(diào)用時,執(zhí)行removeObserver移除所有通知
NSNotificationQueue 通知隊列,根據(jù)發(fā)送和合并策略,發(fā)送通知
- 添加通知到隊列
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray<NSRunLoopMode> *)modes;
- 從隊列移除通知
- (void)dequeueNotificationsMatching:(NSNotification *)notification coalesceMask:(NSUInteger)coalesceMask;
關(guān)于通知隊列的兩個策略:
- 何時發(fā)送
typedef NS_ENUM(NSUInteger, NSPostingStyle) {
NSPostWhenIdle = 1,//空閑時
NSPostASAP = 2,//盡可能快
NSPostNow = 3//立刻
};
- 怎樣合并
typedef NS_OPTIONS(NSUInteger, NSNotificationCoalescing) {
NSNotificationNoCoalescing = 0,//從不
NSNotificationCoalescingOnName = 1,//name 相同的合并
NSNotificationCoalescingOnSender = 2//sender相同的合并
};
asap和whenIdle需要開啟當(dāng)前runloop,并處在添加時的runLoopMode下
-
通知是同步還是異步;
主線程中通知是同步,會等待處理通知的代碼執(zhí)行完才執(zhí)行后面的代碼
子線程中發(fā)送通知,響應(yīng)通知的代碼會在它發(fā)出通知的線程中執(zhí)行,所以是異步的
如果想在子線程發(fā)送通知,主線程響應(yīng)通知就需要手動回調(diào)到主線程執(zhí)行。