作者:YouXianMing 授權本站轉載。
說明
1. 簡化通知中心,筆者曾經實現過不需要移除的通知中心,基於弱引用集合(相對於強引用集合如NSArray,NSDictionary等)編寫,本例子並無太多新意
2. 簡化的通知中心由一個對象組織控制,不需要你手動移除被監聽的對象,這是唯一的一點點有新意的地方
3. 在處理接收通知對象的地方,筆者提供了一個方法來簡化取值操作,相對應的,發送通知消息的時候,被發送的對象也請使用指定的格式(都是用weak修飾,無需擔心被持有)
源碼
https://github.com/YouXianMing/NotificationCenter
// // NotificationCenterObject.h // NotificationCenter // // Created by YouXianMing on 15/7/15. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import @interface PostObject : NSObject @property (nonatomic, strong) NSString *flag; @property (nonatomic, weak) id data; /** * 便利構造器初始化對象 * * @param flag 識別標簽 * @param data 數據 * * @return 實例對象 */ + (instancetype)postObjectWithFlag:(NSString *)flag data:(id)data; /** * 處理通知中心事件 * * @param sender 通知中心的通知對象 * * @return 實例對象 */ + (instancetype)accessNotificationCenterObject:(id)sender; @end /////////////////////////////////////////////////////////////////////////////////////////// @interface NotificationCenterObject : NSObject /** * === 必須先使用此方法進行初始化 === * * 初始化通知中心 * * @param observer 觀察對象 * @param name 注冊標簽 * @param selector 執行用selector * * @return 實例對象 */ + (instancetype)withObserver:(id)observer registerName:(NSString *)name selector:(SEL)selector; /** * 給指定注冊標簽發信息 * * @param name 注冊標簽 * @param postData 發送的對象 */ + (void)postToRegisterName:(NSString *)name data:(PostObject *)postData; @property (nonatomic, readonly, strong) NSString *name; @property (nonatomic, readonly, weak) id observer; /** * 移除 */ - (void)remove; /** * 重新添加上 */ - (void)reAdd; @end /////////////////////////////////////////////////////////////////////////////////////////// /** * 創建通知對象 * * @param flag 標簽 * @param data 傳遞的數據 * * @return 通知對象 */ static inline PostObject * POST_OBJECT(NSString *flag, id data) { return [PostObject postObjectWithFlag:flag data:data]; } /** * 處理通知的對象 * * @param sender 接收的通知對象 * * @return 通知對象 */ static inline PostObject * ACCESS_POST_OBJECT(id sender) { return [PostObject accessNotificationCenterObject:sender]; } /** * 發送通知消息 * * @param name 指定的標簽 * @param postObject 通知的對象 * */ static inline void POST_MSG_TO(NSString *name, PostObject *postObject) { [NotificationCenterObject postToRegisterName:name data:postObject]; } /** * 注冊通知中心 * * @param name 指定的標簽 * @param observer 被注冊的對象 * @param selector 執行的句柄 * * @return 實例對象 */ static inline NotificationCenterObject * REGISTER_MSG_CENTER_WITH(NSString *name, id observer, SEL selector) { return [NotificationCenterObject withObserver:observer registerName:name selector:selector]; }
// // NotificationCenterObject.m // NotificationCenter // // Created by YouXianMing on 15/7/15. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "NotificationCenterObject.h" @implementation PostObject + (instancetype)postObjectWithFlag:(NSString *)flag data:(id)data { PostObject *postObject = [PostObject new]; postObject.flag = flag; postObject.data = data; return postObject; } + (instancetype)accessNotificationCenterObject:(id)sender { PostObject *postData = nil; if ([sender isKindOfClass:[NSNotification class]]) { NSNotification *notiData = sender; if ([notiData.object isKindOfClass:[PostObject class]]) { postData = notiData.object; } } return postData; } @end @interface NotificationCenterObject () @property (nonatomic, strong) NSString *name; @property (nonatomic, weak) id observer; @property (nonatomic) SEL observerSelector; @property (nonatomic) BOOL haveAddObserver; @end @implementation NotificationCenterObject + (void)postToRegisterName:(NSString *)name data:(PostObject *)postData { [[NSNotificationCenter defaultCenter] postNotificationName:name object:postData]; } + (instancetype)withObserver:(id)observer registerName:(NSString *)name selector:(SEL)selector { NotificationCenterObject *notificationCenterObject = [NotificationCenterObject new]; notificationCenterObject.name = name; notificationCenterObject.observer = observer; notificationCenterObject.observerSelector = selector; notificationCenterObject.haveAddObserver = YES; [[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:name object:nil]; return notificationCenterObject; } - (void)remove { if (self.haveAddObserver == YES && _name && _observer) { self.haveAddObserver = NO; [[NSNotificationCenter defaultCenter] removeObserver:_observer name:_name object:nil]; } } - (void)reAdd { if (self.haveAddObserver == NO && _name && _observer) { self.haveAddObserver = YES; [[NSNotificationCenter defaultCenter] addObserver:_observer selector:_observerSelector name:_name object:nil]; } } - (void)dealloc { if (self.haveAddObserver == YES) { NSLog(@"已經釋放"); [[NSNotificationCenter defaultCenter] removeObserver:_observer name:_name object:nil]; } } @end
細節
用內聯函數將OC風格函數簡化為C風格函數,能夠稍微縮短代碼編寫長度,其實並無實用價值,裝的成分居多。