iOS如何實現(xiàn)“多個異步操作結束后執(zhí)行后續(xù)動作”

如何實現(xiàn)多個異步操作結束后執(zhí)行后續(xù)動作

場景:我們可能對列表中的數(shù)據(jù)進行批量操作后,執(zhí)行下一步操作。如多選刪除后,刷新頁面;如多選下載后,提示下載完成。

我們需要用到的一個核心的東西就是信號量:DispatchSemaphore


首先介紹下信號量的基本語法
初始化

swift

let sema = DispatchSemaphore.init(value: 0)

oc

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

可以看出,我們傳了一個 Int 值用于初始化信號量。

兩個核心方法

swift

//等待
sema.wait()
//完成
sema.signal()

oc

//等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
//完成
dispatch_semaphore_signal(sema);

wait會對信號量 -1-1后,如果信號量<0,則會阻塞線程
signal會對信號量 +1


接著讓我們看下信號量的簡單用法
1、單任務實例

以 swift 為例

//1
DispatchQueue.global().async {
    //2
    let sema = DispatchSemaphore.init(value: 0)
    //3
    NetManager.shared().checkPermission(withSpace: model.spaceType, andParentID: parentId, andChildenID: [modid], andAction: "copyFile2All", success: { (result) in
        //4
        sema.signal()
     }) { (msg) in
        //4
        sema.signal()
    }
    //5
    sema.wait()
    //6
}           

代碼解讀:

  1. wait 方法會阻塞主線程,所以需要放在子線程中,本例放在 global 中
  2. 創(chuàng)建信號量對象,信號量為 0
  3. 網絡請求的任務,使用的是AFNetworking
  4. 任務完成,信號量+1
  5. 信號量首先-1,然后檢測信號的值。當信號量<0時阻塞,并一直檢測信號量變化,直到信號量>0時,便會往后執(zhí)行,
  • 注意:使用信號量,一定要放在子線程中,否則主線程會一直阻塞。

如上所示,我們可以在 注釋6的位置寫上我們需要執(zhí)行的代碼。便達到了通過信號量等待一個任務完成后,執(zhí)行下一個任務的要求。

2、多任務實例
DispatchQueue.global().async {
    let sema = DispatchSemaphore.init(value: 0)
    for i in self.selectedItems {
        NetManager.shared().checkPermission(withSpace: model.spaceType, andParentID: parentId, andChildenID: [modid], andAction: "copyFile2All", success: { (result) in
            self.performSegue(withIdentifier: "showDirectoryTreevcID", sender: "copy")
            sema.signal()
        }) { (msg) in
            //
            sema.signal()
        }
    }
    for _ in self.selectedItems {
        sema.wait()
    }
    //刷新 UI 等操作可以放在這里(注:如果是對 UI 操作要放在主線程哦)
    
}

通過單任務實例理解這個多任務的實例應該不難,在此不多做贅述。


總結
  • 上例中的網絡請求方法只是實例用的,讀者可以自己寫個網絡請求替換掉
  • 信號量有三個比較關鍵的點(信號量的值,wait 方法,signal 方法),理解透了用起來很簡單,且好用
  • 信號量的初始化的值在本例中為 0,如果是正整數(shù),一般用于多任務線程池(比如同時最大支持n 個任務上傳)。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容