你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> GLPubSub

GLPubSub

編輯:IOS開發基礎

前言

我們計劃通過 blog 和開源的方式,分享一些我們在開發 Glow 和 Nurture 的過程中積累的開發經驗。GLPubSub 作為開源計劃的第一步,是一個代碼量較少,但很實用的 Category。

GitHub 

Documentation
Notification 作為發布訂閱模式(觀察者模式)的一種,在 iOS App 的開發過程中很常見,GLPubSub 是 NSNotificationCenter 的封裝,目標是簡化 iOS 開發中的發布訂閱模式。因為是 NSObject 的 Category,所以可以在任意 NSObject 的子類上使用。

安裝

CocoaPods

如果通過 CocoaPods 管理第三方依賴,你可以:

  • 在 Podfile 裡添加以下依賴:

pod "GLPubSub", "~> 1.0"
  • 運行 pod install 來安裝 GLPubSub

源文件

如果你的項目沒有用 CocoaPods 來管理第三方依賴,你也可以直接導入源文件。

  • 下載最新代碼並解壓

  • 導入 NSObject+GLPubSub.h 和 NSObject+GLPubSub.m 到你的工程,記得在導入時勾選 "Copy items if needed"

使用

因為 GLPubSub 是基於 NSNotificationCenter 並注冊在 [NSNotificationCenter defaultCenter] 的,所以 GLPubSub 也支持大部分系統通知,例如 UIApplicationDidEnterBackgroundNotification,UIApplicationDidBecomeActiveNotification,UITextFieldTextDidChangeNotification 等等,但是轉發的過程中會丟棄系統通知的 userInfo 字段。

設置 PubSub 的隊列

GLPubSub 主要基於 NSNotificationCenter 的 -addObserverForName:object:queue:usingBlock: 方法。你可以調用 NSObject 的 +setPubSubQueue: 方法來設置傳入該方法的 queue。

默認傳入的 queue 為 nil,這意味著所有事件會在發布通知的線程中被執行。你可以手動設置為 [NSOperationQueue maniQueue] 使得所有事件在主線程被觸發:

[NSObject setPubSubQueue:[NSOperationQueue mainQueue]];

通過 Selector 訂閱事件

大部分時候,我們用 self 作為訂閱者:

[self subscribe:@"YourEventName" selector:@selector(yourEventHandler)];

你也可以指定事件的發布者:

[self subscribe:@"YourEventName" obj:somePublisher selector:@selector(yourEventHandler)];

如果你希望你的方法只觸發一次,你可以用:

[self subscribeOnce:@"YourEventName" selector:@selector(yourEventHandler)];

這樣當該事件被觸發後,就會自動取消訂閱。

你的方法可以接受一個 GLEvent 參數,該參數包含了被觸發事件的相關信息。

@interface GLEvent : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) id obj;
@property (nonatomic, retain) id data;

name 是事件名,obj 是發布者,data 是附加信息。

通過 Block 訂閱事件

方法與上面通過 selector 訂閱的方法類似:

GLEventHandler 定義如下:

typedef void (^GLEventHandler)(GLEvent *event);

所以你可以如下用 block 訂閱一個事件:

__weak __typeof__(self) weakSelf = self;  
[self subscribe:UIApplicationDidEnterBackgroundNotification handler:^(GLEvent *event) {
    __strong __typeof__(weakSelf) strongSelf = weakSelf;
    [strongSelf appDidEnterBackground];
}];

這裡的 weak 化是為了避免循環引用。對應於前面 selector 的方法,用 block 也有 4 種調用方法:

- (id)subscribe:(NSString *)eventName handler:(GLEventHandler)handler;
- (id)subscribe:(NSString *)eventName obj:(id)obj handler:(GLEventHandler)handler;
- (id)subscribeOnce:(NSString *)eventName handler:(GLEventHandler)handler;
- (id)subscribeOnce:(NSString *)eventName obj:(id)obj handler:(GLEventHandler)handler;

取消訂閱

取消訂閱某個事件:

- (void)unsubscribe:(NSString *)eventName;

取消訂閱所有事件:

- (void)unsubscribeAll;

雖然當實例被銷毀時,存在 associated object 中的觀察者也都會被銷毀,但還是建議手動取消訂閱,如根據不同需求,在 -dealloc 或 -viewDidDisappear 方法中取消訂閱。

- (void)dealloc
{
    [self unsubscribeAll];
}

發布事件

你可以簡單地發布一個事件:

[self publish:@"YourEventName"];

也可以附帶一些數據,很多時候我們會傳入一個 NSDictionary 來附帶更多結構化的數據:

[self publish:@"YourEventName" data:@{@"key": value}]

循環引用

因為所有生成的觀察者都會被 self 引用,所以當你的 block 引用 self 的時候就會形成循環引用導致實例無法被釋放,所以你必須 weakify self。強烈推薦用 libextobjc 中的 EXTScope 來做 

weakify/strongify:
@weakify(self);
[self subscribe:UIApplicationDidEnterBackgroundNotification handler:^(GLEvent *event) {
    @strongify(self);
    [self appDidEnterBackground];
}];

License

GLPubSub 基於 MIT 協議開源,詳見 LICENSE 文件。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved