iOS管理多個彈窗彈出-信號量應(yīng)用

問題和需求

APP在啟動完成后,一般會在首頁有多個彈窗,這些彈窗大多都是自定義的,網(wǎng)絡(luò)回來的時機也不一定。因此多個彈窗如果不做處理就會一起全部彈出來,這樣會比較影響體驗,如果沒有好的管理方法,那么維護就變得困難。
先附上效果對比圖


QQ20190520-121517-HD.gif

這個效果是通過信號量實現(xiàn)的

信號量概念
信號量是用于多線程同步的,跟鎖不一樣的是,信號量不一定是鎖定某一個資源,而是流程上的概念,比如:有A,B兩個線程,B線程要等A線程完成某一任務(wù)以后再進行自己下面的步驟,這個任務(wù) 并不一定是鎖定某一資源,還可以是進行一些計算或者數(shù)據(jù)處理之類。而對于鎖來說,鎖住的資源無法被其余的線程訪問,從而阻塞線程而實現(xiàn)線程同步。

實現(xiàn)
首先創(chuàng)建一個類AlertViewManager,實現(xiàn)單例,用于管理項目中的所有的彈窗,可以是自定義的彈窗、原生彈窗、權(quán)限申請的彈窗

代碼建議拉到末尾下載DEMO,粘貼代碼到簡書有些空格不見了

AlertViewManager.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedefvoid(^ExecuteBlock)(void);
@interfaceAlertViewManager :NSObject
//重要提醒!:自定義的彈窗不要添加再[UIApplication sharedApplication].keyWindow上, keyWindow是會變化的,因為系統(tǒng)的彈窗是創(chuàng)建一個window,成為keyWindow,當(dāng)系統(tǒng)彈窗消失的時候,創(chuàng)建出來的window也會銷毀,但是這時候獲取的keyWindow有可能就是準(zhǔn)備銷毀這個.這樣的自定義彈窗連同keywindow一起被銷毀,導(dǎo)致信號一直是鎖著的狀態(tài),無法彈出后面的彈窗
//系統(tǒng)彈窗消失瞬間獲取到的keyWindow就是系統(tǒng)彈窗那個keyWindow,自定義彈窗添加上去會隨著keywindow銷毀而銷毀
+ (nullable instancetype)shareManager;
/**
 彈窗顯示的代碼寫進BLOCK塊內(nèi)
 @paramexecuteBlock <#executeBlock description#>
 */
- (void)showWithExecuteBlock:(nonnull ExecuteBlock)executeBlock;
/**
 彈窗顯示完畢調(diào)用
 @paramexecuteBlock 可以為空但是一定要調(diào)用
 */
- (void)dismissWithExecuteBlock:(nullable ExecuteBlock)executeBlock;
@end

AlertViewManager.m

#import "AlertViewManager.h"
//全局信號量
dispatch_semaphore_t_globalInstancesLockSEM;
//執(zhí)行QUEUE的Name
char*QUEUE_NAME_SEM ="com.alert.queueSEM";
//初始化 -- 借鑒YYWebImage的寫法
staticvoid_AlertViewInitGlobalSEM() {
    staticdispatch_once_tonceToken;
    dispatch_once(&onceToken, ^{
        _globalInstancesLockSEM = dispatch_semaphore_create(1);
    });
}

@interface AlertViewManager ()
@end
@implementationAlertViewManager
- (void)showWithExecuteBlock:(ExecuteBlock)executeBlock {
    dispatch_async(dispatch_queue_create(QUEUE_NAME_SEM, DISPATCH_QUEUE_SERIAL), ^{
        dispatch_semaphore_wait(_globalInstancesLockSEM, DISPATCH_TIME_FOREVER);
        dispatch_async(dispatch_get_main_queue(), ^{
            if(executeBlock) {
                executeBlock();
            }
        });
    });
}

- (void)dismissWithExecuteBlock:(ExecuteBlock)executeBlock {
    dispatch_async(dispatch_queue_create(QUEUE_NAME_SEM, DISPATCH_QUEUE_SERIAL), ^{
        dispatch_semaphore_signal(_globalInstancesLockSEM);
        dispatch_async(dispatch_get_main_queue(), ^{
            if(executeBlock) {
                executeBlock();
            }
        });
    });
}

+ (instancetype)shareManager {
    return[[self alloc]init];
}

+ (instancetype)allocWithZone:(struct_NSZone*)zone {
    staticidinstan =nil;
    staticdispatch_once_tonceToken;
    dispatch_once(&onceToken, ^{
        instan = [superallocWithZone:zone];
    });
    returninstan;
}

- (instancetype)init {
    if(self= [superinit]) {
        _AlertViewInitGlobalSEM();
    }
    return self;
}
@end

使用方法

系統(tǒng)原生彈窗調(diào)用如下

[[AlertViewManager shareManager] showWithExecuteBlock:^{
        [[[UIAlertView alloc] initWithTitle:@"" message:@"彈窗1" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil] show];
    }];
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    [[AlertViewManager shareManager] dismissWithExecuteBlock:^{
    }];
}

重要提醒!:

1.自定義的彈窗不要添加再[UIApplication sharedApplication].keyWindow上, keyWindow是會變化的,因為系統(tǒng)的彈窗是創(chuàng)建一個window,成為keyWindow,當(dāng)系統(tǒng)彈窗消失的時候,創(chuàng)建出來的window也會銷毀,但是這時候獲取的keyWindow有可能就是準(zhǔn)備銷毀這個.這樣的自定義彈窗連同keywindow一起被銷毀,導(dǎo)致信號一直是鎖著的狀態(tài),無法彈出后面的彈窗

2.showWithExecuteBlock和dismissWithExecuteBlock要成對出現(xiàn)。如果沒有成對出現(xiàn),信號量計數(shù)錯誤,會同時彈出多個彈窗或者不彈出

附上Demo: https://github.com/1498522607/HZSAlertViewManager
有什么問題歡迎評論留言

參考并推薦閱讀優(yōu)秀文章

http://www.itdecent.cn/p/2f0225b67f6c

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

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

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,637評論 1 32
  • 時間是尺子,人們用它感知生命的流逝,用它來制定各種計劃,用它來衡量工作效率...... 古時候,人們用日晷,圭表,...
    張大俠丶閱讀 371評論 3 3
  • 第二話 有些人不必客氣 高貴華麗的歐式餐廳中,一個清秀俊郎的年輕男子安靜的坐在餐桌前。白皙的干凈的臉龐上看不...
    殤祁祁閱讀 280評論 2 3
  • 李開復(fù)在1月份上了CBS的60minutes欄目,一下子把這本書的英文版帶火了。這本書的英文名是《AI強國》,中文...
    SeanCheney閱讀 4,515評論 0 9
  • 一個島國下面有7個島,各島人數(shù)不一樣。旅行者已經(jīng)在其中一個島上,他要去各島游歷,準(zhǔn)備在人口多的島上游玩的時間長一些...
    DataMining234閱讀 725評論 0 1

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