Swift - 使用DispatchGroup处理多线程并发操作与简化代码

使用场景

1、简化代码易读性,似的获取数据与界面刷新分离

2、处理多线程并发执行,处理多任务请求结束后的UI刷新问题

3、与网络请求第三方的混合使用

一、创建DispatchGroup与简单实用

创建队列组

lazy var gropQueue:DispatchGroup = {

        let grop:DispatchGroup = DispatchGroup.init()

        return grop

    }()

简单的模拟DispatchGroup与DispatchQueue使用

func textGroup() -> Void {
        let queue:DispatchQueue = DispatchQueue.init(label: "textQueue")
        // 队列queue加入队列组
        queue.async (group: self.gropQueue){
            /*任务一*/
        }
        self.gropQueue.notify(queue: DispatchQueue.main) {
            /*界面处理*/
        }
    }

模拟多任务并发处理

func textMoreQueue() -> Void {
        let queue1:DispatchQueue = DispatchQueue.init(label: "textQueue1")
        let queue2:DispatchQueue = DispatchQueue.init(label: "textQueue2")
        let queue3:DispatchQueue = DispatchQueue.init(label: "textQueue3")
        // 队列queue加入队列组
        queue1.async (group: self.gropQueue){
            /*任务1*/
        }
        queue2.async (group: self.gropQueue){
            /*任务2*/
        }
        queue3.async (group: self.gropQueue){
            /*任务3*/
        }
        
        /*三个异步任务完成后执行界面处理操作*/
        self.gropQueue.notify(queue: DispatchQueue.main) {
            /*界面处理*/
        }
    }

以上是通过创建异步线程进行任务处理操作,一款app中最重要的就是数据与界面!下面我们从简单到复杂去处理异步请求与界面刷新

二、网络请求第三方的混合使用

在异步线程中的回调方法中去刷新界面

/*获取推荐列表*/
    func getInfomation() -> Void {
        let requestUrl:String = "https://www.apiopen.top/novelApi"
        Alamofire.request(requestUrl, method: .get).responseJSON { (response) in
            if let json = response.result.value {
                let jsonDic:Dictionary<String,Any> = json as! Dictionary
                let array:Array<Any> = jsonDic["data"] as! Array
                self.allArray.append(array)
                /*处理界面数据刷新界面*/
            } else {
            }
        }
    }

上述代码是我们常见的异步请求与界面刷新的组合方式之一、其优点在于代码结果简单易读,缺陷是如果我们返回的数据含有多种数据结果,例如这个推荐列表放回的数据结果有四种数据结构,在请求数据的异步线程中去处理请求得到的数据会使代码表现的非常臃肿不雅!

修改后的代码

var allArray:Array<Any> = Array()
    lazy var gropQueue:DispatchGroup = {
        let grop:DispatchGroup = DispatchGroup.init()
        return grop
    }()

/*获取数据*/
    func getRequestData() -> Void {
        let queue:DispatchQueue = DispatchQueue.init(label: "handleDataQueue")
        /*获取网络数据*/
        self.gropQueue.enter()
        self.getInfomation()
        
        /*处理获取的数据*/
        self.gropQueue.notify(queue: DispatchQueue.main) {
            self.handleDatas()
            self.gropQueue.leave()
        }
        
        /*进行界面处理*/
        self.gropQueue.notify(queue: queue) {
            self.updateUI()
        }
        
    }


/*获取推荐列表*/
    func getInfomation() -> Void {
        let requestUrl:String = "https://www.apiopen.top/novelApi"
        Alamofire.request(requestUrl, method: .get).responseJSON { (response) in
            if let json = response.result.value {
                let jsonDic:Dictionary<String,Any> = json as! Dictionary
                let array:Array<Any> = jsonDic["data"] as! Array
                self.allArray.append(array)
                self.gropQueue.leave()
                
            } else {
                self.gropQueue.leave()
            }
        }
    }

/*刷新总列表*/
    func updateUI() -> Void {
        print("allArray:\(self.allArray)")
    }

/*异步线程处理数据*/
    func handleDatas() -> Void {
        print("data:\(self.allArray)")
    }

如上代码可以看出对臃肿的代码进行了提取分离,使得代码可读性提高

三、简单的并发执行的任务

最简单的多线程任务处理

func textMoreQueue() -> Void {
        let queue1:DispatchQueue = DispatchQueue.init(label: "textQueue1")
        let queue2:DispatchQueue = DispatchQueue.init(label: "textQueue2")
        let queue3:DispatchQueue = DispatchQueue.init(label: "textQueue3")
        // 队列queue加入队列组
        queue1.async (group: self.gropQueue){
            /*任务1*/
        }
        queue2.async (group: self.gropQueue){
            /*任务2*/
        }
        queue3.async (group: self.gropQueue){
            /*任务3*/
        }
        
        /*三个异步任务完成后执行界面处理操作*/
        self.gropQueue.notify(queue: DispatchQueue.main) {
            /*界面处理*/
        }
    }

复杂的多任务处理,例如多线程去获取网络数据,处理网络数据,处理的结果结束后进行界面刷新操作

var allArray:Array<Any> = Array()
lazy var gropQueue:DispatchGroup = {
     let grop:DispatchGroup = DispatchGroup.init()
     return grop
 }()


/*使用线程组*/
    func getData() -> Void {
        let handleQueue:DispatchQueue = DispatchQueue.init(label: "handleQueue")
        /*获取推荐列表*/
        self.gropQueue.enter()
        self.getInfomation()
        /*获取图片*/
        self.gropQueue.enter()
        self.getImage()
        /*进行线程处理*/
        self.gropQueue.notify (queue:handleQueue){
            self.handleDatas()
        }
        
        self.gropQueue.notify(queue: DispatchQueue.main) {
            self.updateUI()
        }
    }

/*获取推荐列表*/
    func getInfomation() -> Void {
        let requestUrl:String = "https://www.apiopen.top/novelApi"
        Alamofire.request(requestUrl, method: .get).responseJSON { (response) in
            if let json = response.result.value {
                let jsonDic:Dictionary<String,Any> = json as! Dictionary
                let array:Array<Any> = jsonDic["data"] as! Array
                self.allArray.append(array)
                self.gropQueue.leave()
                
            } else {
                self.gropQueue.leave()
            }
        }
    }
    
    /*获取图片列表*/
    func getImage() -> Void {
        let requestUrl:String = "https://www.apiopen.top/meituApi?page=1"
        Alamofire.request(requestUrl).responseJSON { (response) in
            if let json = response.result.value {
                let jsonDic:Dictionary<String,Any> = json as! Dictionary
                let array:Array<Any> = jsonDic["data"] as! Array
                self.allArray.append(array)
                self.gropQueue.leave()
            } else {
                self.gropQueue.leave()
            }
        }
    }

/*异步线程处理数据*/
    func handleDatas() -> Void {
        print("data:\(self.allArray)")
    }

综合练习;要求如下;热门数据分别有四部分组成,热门订场,热门赛事,热门培训,热门健康

代码如下

var hotOperationArray:Array<Any> = Array()

var groupQueue:DispatchGroup = {
        let group:DispatchGroup = DispatchGroup.init()
        return group
    }()

lazy var manager:HttpRequestManager = {
        let man:HttpRequestManager = HttpRequestManager()
        return man
    }()


func getDatas() -> void {
    MBProgressHUD.showAdded(to: self.view, animated: true)
    self.groupQueue.enter()
    self.getHotOperation()
    self.groupQueue.enter()
    self.getHotActivity()
    self.groupQueue.notify(queue: DispatchQueue.main) {
          MBProgressHUD.hide(for: self.view, animated: true)
            /*表格数据刷新*/
        }
}



/*热门数据*/
    func getHotOperation() -> Void {
        let manager:HttpRequestManager = HttpRequestManager()
        MBProgressHUD.showAdded(to: self.view, animated: true)
        let locationModel:LocationModel = LocationModel.shareLocationModel()
        let parameter:Parameters = ["latitude":locationModel.latitude,"longitude":locationModel.longitude]
        manager.getHotHealth(parameter: parameter, urlStr: "match/queryLove")
        manager.requsetBlockSucceed = { json in
            MBProgressHUD.hide(for: self.view, animated: true)
            let jsonDic:Dictionary<String,Any> = json as! Dictionary
            let jsonData:Dictionary<String,Any> = jsonDic["data"] as! Dictionary
            /*model数据源
             * siteDic 讲座
             * matchArray 比赛
             * trainArray 培训
             * let singArray:Array<Any> = jsonData["sing"] as! Array<Any> // 其他
             */
            let siteDic:Dictionary<String,Any> = jsonData["site"] as! Dictionary<String, Any>
            let matchArray:Array<Any> = jsonData["match"] as! Array<Any>
            let trainArray:Array<Any> = jsonData["train"] as! Array<Any>
            BaseGoodsModel.mj_setupReplacedKey(fromPropertyName: { () -> [AnyHashable : Any]? in
                return ["goodsId":"id"]
            })
            let siteModel:SiteModel = SiteModel.mj_object(withKeyValues: siteDic)
            let matchModelArray:Array<MatchModel> = MatchModel.mj_objectArray(withKeyValuesArray: matchArray) as! Array<MatchModel>
            let trainModelArray:Array<TrainModel> = TrainModel.mj_objectArray(withKeyValuesArray: trainArray) as! Array<TrainModel>
            self.hotOperationArray.append(siteModel)
            self.hotOperationArray.append(matchModelArray)
            self.hotOperationArray.append(trainModelArray)
        }
        manager.requsetBlockDefeated  = { error in
            self.groupQueue.leave()
        }
    }

 /*热门健康咨询*/
    func getHotActivity() -> Void {
        let manager:HttpRequestManager = HttpRequestManager()
        MBProgressHUD.showAdded(to: self.view, animated: true)
        let parameter:Parameters = ["pageNum":1, "pageSize":1]
        manager.getHotOption(parameter: parameter, urlStr: "/fitness/pageAll")
        manager.requsetBlockSucceed = { json in
            MBProgressHUD.hide(for: self.view, animated: true)
            HotFitnessModel.mj_setupIgnoredPropertyNames({ () -> [Any]? in
                return ["status","labels","time"]
            })
            HotFitnessModel.mj_setupReplacedKey(fromPropertyName: { () -> [AnyHashable : Any]? in
                return ["hotId":"id"]
            })
            let jsonDic:Dictionary<String,Any> = json as! Dictionary
            let dataDic:Dictionary<String,Any> = jsonDic["data"] as! Dictionary
            let listArray:Array<Any> = dataDic["list"] as! Array<Any>
            let modelArray:Array<HotFitnessModel> = HotFitnessModel.mj_objectArray(withKeyValuesArray: listArray) as! Array<HotFitnessModel>
            self.hotOperationArray.append(modelArray)
            
            self.groupQueue.leave()
        }
        manager.requsetBlockDefeated  = { error in
            self.groupQueue.leave()
        }
    }

猜你喜欢

转载自blog.csdn.net/die_word/article/details/80797329