隊(duì)列組的應(yīng)用

開(kāi)發(fā)中,如果我們需要同時(shí)開(kāi)啟多條線程下載數(shù)據(jù),并且等待這多條線程執(zhí)行完畢,即數(shù)據(jù)下載完成后,再來(lái)對(duì)這多個(gè)數(shù)據(jù)進(jìn)行操作。這樣的需求在項(xiàng)目開(kāi)發(fā)中還是比較常見(jiàn)的,那么有什么比較好的方法可以實(shí)現(xiàn)這樣的需求呢?答案是:隊(duì)列組。

下面就針對(duì)這個(gè)問(wèn)題分別展開(kāi)研究。

1、異步下載兩種圖片,分別合并之后再回到主線程刷新UI

/// 異步下載兩種圖片,分別合并之后再回到主線程刷新UI
- (void)mergedImages1 {
    
    // 異步下載
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        // 1.下載第1張
        UIImage *image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl1]]];
        
        // 2.下載第2張
        UIImage *image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl2]]];
        
        // 3.合并圖片
        // 開(kāi)啟一個(gè)位圖上下文
        UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
        
        // 繪制第1張圖片
        CGFloat image1W = image1.size.width;
        CGFloat image1H = image1.size.height;
        [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
        
        // 繪制第2張圖片
        CGFloat image2W = image2.size.width;
        CGFloat image2H = image2.size.height * 0.5;
        CGFloat image2Y = image1H * 0.5;
        [image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
        
        // 得到上下文中的圖片
        UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
        
        // 結(jié)束上下文
        UIGraphicsEndImageContext();
        
        // 4.回到主線程顯示圖片
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imgView.image = fullImage;
        });
    });
}

2、分別開(kāi)啟兩條線程下載圖片,然后再判斷圖片是否下載成功,最后合并完圖片之后回到住線程刷新UI

/// 分別開(kāi)啟兩條線程下載圖片,然后再判斷圖片是否下載成功,最后合并完圖片之后回到住線程刷新UI
- (void)mergedImages2 {
    
    // 異步下載
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        // 1.下載第1張
        UIImage *image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl3]]];
        self.image1 = image1;
        
        [self bindImages];
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        // 2.下載第2張
        UIImage *image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl4]]];
        self.image2 = image2;
        
        [self bindImages];
    });
}

- (void)bindImages {
    
    if (self.image1 == nil || self.image2 == nil) return;
    
    // 3.合并圖片
    // 開(kāi)啟一個(gè)位圖上下文
    UIGraphicsBeginImageContextWithOptions(self.image1.size, NO, 0.0);
    
    // 繪制第1張圖片
    CGFloat image1W = self.image1.size.width;
    CGFloat image1H = self.image1.size.height;
    [self.image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
    
    // 繪制第2張圖片
    CGFloat image2W = self.image2.size.width;
    CGFloat image2H = self.image2.size.height * 0.5;
    CGFloat image2Y = image1H * 0.5;
    [self.image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
    
    // 得到上下文中的圖片
    UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
    
    // 結(jié)束上下文
    UIGraphicsEndImageContext();
    
    // 4.回到主線程顯示圖片
    dispatch_async(dispatch_get_main_queue(), ^{
        self.imgView.image = fullImage;
    });
}

3、利用隊(duì)列組方式,輕松實(shí)現(xiàn)

/// 利用隊(duì)列組方式,輕松實(shí)現(xiàn)
- (void)queueGroupImplementation {
    
    // 1.隊(duì)列組
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.下載圖片1
    __block UIImage *image1 = nil;
    dispatch_group_async(group, queue, ^{
        
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl5]]];
        image1 = image;
    });
    
    // 3.下載圖片2
    __block UIImage *image2 = nil;
    dispatch_group_async(group, queue, ^{
        
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl6]]];
        image2 = image;
    });
    
    // 4.合并圖片 (保證執(zhí)行完組里面的所有任務(wù)之后,再執(zhí)行notify函數(shù)里面的block)
    dispatch_group_notify(group, queue, ^{
        
        // 開(kāi)啟一個(gè)位圖上下文
        UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
        
        // 繪制第1張圖片
        CGFloat image1W = image1.size.width;
        CGFloat image1H = image1.size.height;
        [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
        
        // 繪制第2張圖片
        CGFloat image2W = image2.size.width;
        CGFloat image2H = image2.size.height * 0.5;
        CGFloat image2Y = image1H * 0.5;
        [image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
        
        // 得到上下文中的圖片
        UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
        
        // 結(jié)束上下文
        UIGraphicsEndImageContext();
        
        // 5.回到主線程顯示圖片
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imgView.image = fullImage;
        });
    });
}

最終實(shí)現(xiàn)的UI顯示如下圖:


Simulator Screen Shot - iPhone 11 Pro Max - 2020-04-30 at 13.52.39.png

這里是主要的實(shí)現(xiàn)邏輯部分代碼,具體步驟請(qǐng)各位朋友下載demo自行查閱!

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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