通知中心事件執(zhí)行隊(duì)列

問題

在向通知中心注冊(cè)事件監(jiān)聽時(shí),有兩個(gè)問題:

  • 不會(huì)去重,即每一次addObserver都會(huì)添加一次監(jiān)聽,當(dāng)事件發(fā)生時(shí),回調(diào)方法就會(huì)被多次調(diào)用(故意多次監(jiān)聽的除外)。
  • 回調(diào)的順序不能依賴代碼來指定,即沒有回調(diào)任務(wù)執(zhí)行順序這類機(jī)制存在。

以上,封裝一個(gè)工具,在注冊(cè)監(jiān)聽時(shí),傳入任務(wù)名(ID)和優(yōu)先級(jí)來解決這些問題。

JXNotificationPriorityHelper.gif

核心代碼

JXNotificationPriorityManager.h

/// 傳入通知名,返回實(shí)例。通知名對(duì)應(yīng)的實(shí)例是全局唯一。
+ (nonnull instancetype)managerWithNotificationName:(nonnull NSString *)notificationName;

/// 添加任務(wù)。name任務(wù)名唯一;priority指定優(yōu)先級(jí)
- (void)addTaskWithName:(nonnull NSString *)name priority:(JXNotificationPriority)priority action:(nonnull JXNotificationPriorityManagerActionBlock)action;

/// 移除任務(wù)
- (void)removeTaskForName:(nonnull NSString *)name;

JXNotificationPriorityManager.m

+ (instancetype)managerWithNotificationName:(NSString *)notificationName {
    NSAssert(notificationName, @"通知名不能為空");
    
    static NSMutableDictionary *managers;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        managers = [NSMutableDictionary dictionary];
    });
    JXNotificationPriorityManager *manager = managers[notificationName];
    if (!manager) {
        manager = [[JXNotificationPriorityManager alloc] init];
        managers[notificationName] = manager;
        
        [[NSNotificationCenter defaultCenter] addObserver:manager selector:@selector(didReceivedNotification:) name:notificationName object:nil];
    }
    return manager;
}

- (void)didReceivedNotification:(NSNotification *)notification {
    NSArray<NSNumber *> *descendSorted = [[self.queueData allKeys] sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        NSNumber *num1 = obj1;
        NSNumber *num2 = obj2;
        if (num1 == num2) {
            return NSOrderedSame;
        }
        return [num1 integerValue] < [num2 integerValue] ? NSOrderedDescending : NSOrderedAscending;
    }];
    
    [descendSorted enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSArray<NSString *> *blockNameArray = self.queueData[obj];
        [blockNameArray enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            JXNotificationPriorityManagerActionBlock block = self.blocks[obj];
            block(notification);
        }];
    }];
}

- (void)addTaskWithName:(NSString *)name priority:(JXNotificationPriority)priority action:(nonnull JXNotificationPriorityManagerActionBlock)action {
    if (!name || !action) {
        return;
    }
    name = [name copy];
    
    self.blocks[name] = action;
    self.priorities[name] = @(priority);
    
    NSMutableArray<NSString *> *blockNameArray = self.queueData[@(priority)];
    if (!blockNameArray) {
        blockNameArray = [NSMutableArray array];
        self.queueData[@(priority)] = blockNameArray;
    }
    
    if ([blockNameArray containsObject:name]) {
        [blockNameArray removeObject:name];
    }
    [blockNameArray addObject:name];
}

- (void)removeTaskForName:(NSString *)name {
    if (!name) {
        return;
    }
    name = [name copy];
    
    NSNumber *priority = self.priorities[name];
    NSMutableArray<NSString *> *blockNameArray = self.queueData[priority];
    [blockNameArray removeObject:name];
    
    [self.blocks removeObjectForKey:name];
    [self.priorities removeObjectForKey:name];
}

另外,考慮如果引入異步回調(diào)的話,那么執(zhí)行優(yōu)化級(jí)的意義就不大了,所以本工具以同步方式逐個(gè)任務(wù)回調(diào)。

項(xiàng)目源碼:https://github.com/JiongXing/JXNotificationPriorityManager

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,940評(píng)論 25 709
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,263評(píng)論 6 342
  • 其實(shí)說實(shí)話我也不知道自己到底想表達(dá)什么 但就是有好多話想說 或是吐槽或是抱怨或是對(duì)自己這些天的狗血經(jīng)歷的反思 并沒...
    King木子木木亦大閱讀 254評(píng)論 0 0
  • 突然有那么一天,開始不想約朋友,感覺自己時(shí)間不夠用,想把工作睡眠以外的時(shí)間用來休息....就這樣我慢慢喜歡一個(gè)人獨(dú)...
    MIUAnnie閱讀 229評(píng)論 0 0
  • 這個(gè)題目太大,且對(duì)于康波和區(qū)塊連,我都是剛?cè)腴T的學(xué)生。 這篇文章不僅難以拿出有實(shí)際價(jià)值意義的結(jié)論,...
    Kuiper_belt閱讀 226評(píng)論 0 0

友情鏈接更多精彩內(nèi)容