中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Swift多線程:使用GCD實(shí)現(xiàn)異步下載圖片

2018-07-20    來(lái)源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

GCD屬于系統(tǒng)及的線程管理,功能很強(qiáng)大,比上兩次咱們分享的Operation要強(qiáng)大。有很多老前輩們已經(jīng)創(chuàng)造了非常非常多的資料介紹GCD,因?yàn)榇蠹叶际前袵CD放在了多線程內(nèi)容分享的最開(kāi)始,所以導(dǎo)致好多好多理論知識(shí)都被放在了GCD部分。

哈哈~幸好非典型技術(shù)宅英明神武的錯(cuò)峰出行,把一些基礎(chǔ)概念放在了上兩篇文章里面。極大的減輕了這篇文章的閱讀負(fù)擔(dān)。

既然前人都早了辣么多輪子,俺就不想再多介紹一些基礎(chǔ)理論知識(shí)了。反正碼再多的字,只會(huì)讓大家立刻馬上關(guān)掉這篇文章。而且上一篇關(guān)于Operation的閱讀量就明顯不高,看來(lái)大家不喜歡看啊。。。

那就容我偷偷懶嘛~重點(diǎn)還是分享一些代碼吧。

不是說(shuō)理論知識(shí)不重要啊,面試全都問(wèn)這個(gè)。而且理論知識(shí)直接影響到對(duì)技術(shù)的理解深度,決定能在這條路上走多遠(yuǎn)。是會(huì)成為某個(gè)領(lǐng)域的大牛,還是只是簡(jiǎn)單的應(yīng)用者。

1. GCD基礎(chǔ)知識(shí)

納尼?不是說(shuō)不說(shuō)基本概念了嗎?easy~easy~~easy~~~只介紹一些那些最最重要的,不了解就會(huì)影響到閱讀這篇文章的內(nèi)容啦。

其實(shí)GCD和Operation很多地方驚人的相似。廢話,都是多線程,底層都差不多,能不相似嘛!

GCD使用只需要兩步:

  • STEP ONE:創(chuàng)建任務(wù)。

  • STEP TWO:把任務(wù)放進(jìn)隊(duì)列里。

。。。。。。~!@#¥%……&*¥%#@![email protected]#¥%…… 把大象放進(jìn)冰箱里需要幾步?!兩步!打開(kāi)冰箱門(mén),把大象放進(jìn)去!宅胖,現(xiàn)在很想抽死你啊!

確實(shí)真的就是這樣的這只是為了騙你入門(mén),讓你覺(jué)得好簡(jiǎn)單。

1.1 任務(wù)的分類(lèi)

上面說(shuō)了任務(wù),任務(wù)只有兩種方式:同步、異步。

  • 異步(asynchronous)具備開(kāi)啟新線程的能力,也具備跳過(guò)當(dāng)前代碼繼續(xù)往下執(zhí)行的能力。

  • 同步(synchronous)不具備開(kāi)啟新線程的能力,也不具備跳過(guò)當(dāng)前代碼繼續(xù)往下執(zhí)行的能力。

換句話簡(jiǎn)單的說(shuō),異步任務(wù)就是可以同時(shí)開(kāi)啟多個(gè)跑道,同時(shí)跑好多輛車(chē)。同步就是只有一條車(chē)道,堵死也飛不過(guò)去,只能乖乖的等著,一輛接一輛。

任務(wù)放入到隊(duì)列里面,會(huì)遵循first in first out原則。舉個(gè)惡心的例子,就像是吃飯后嘔吐,后吃進(jìn)去的先吐出來(lái),先吃的東西后吐出來(lái)。

哈哈~看了這個(gè)比方,別打死我~

1.2 隊(duì)列的分類(lèi)

隊(duì)列吶,也只有兩種:串行隊(duì)列(Serial Dispatch Queue)、并發(fā)隊(duì)列(Concurrent Dispatch Queue)。

  • 串行隊(duì)列(Serial Dispatch Queue):

讓任務(wù)一個(gè)接著一個(gè)有序的執(zhí)行,一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)。

  • 并發(fā)隊(duì)列(Concurrent Dispatch Queue)

可以讓多個(gè)任務(wù)同時(shí)執(zhí)行,自動(dòng)開(kāi)啟多個(gè)線程同時(shí)執(zhí)行多個(gè)任務(wù)。

咦?有點(diǎn)暈,怎么感覺(jué)跟剛才的任務(wù)分類(lèi)一樣吶?沒(méi)錯(cuò)!就是這樣的。

下面為了讓大家不要暈菜,我們把隊(duì)列這個(gè)中文名字統(tǒng)一都叫做Queue,這樣就和OperationQueue對(duì)應(yīng)起來(lái)了,就不會(huì)那么暈了。

Serial Queue和Concurrent Queue各自都有一個(gè)特殊的Queue。

  • 主隊(duì)列(main queue):是Serial Queue中特殊的一種。只能在主線程中進(jìn)行,并且主隊(duì)列里面的任務(wù),只有當(dāng)主線程空閑的時(shí)候才能被執(zhí)行。用來(lái)刷新UI使用。

  • 全局隊(duì)列(global queue):是Concurrent Queue中特殊的一種。用來(lái)執(zhí)行耗時(shí)操作。

同時(shí),GCD里面還可以自定義Queue。

1.3 排列組合開(kāi)始

最開(kāi)始的時(shí)候,咱們是不是說(shuō)了,使用GCD就只有兩步:創(chuàng)建任務(wù),把任務(wù)放進(jìn)Queue里。

任務(wù)有兩種:同步、異步。Queue加上兩種特殊的(不包括自定義的)一共有四種。來(lái)吧,開(kāi)始排列組合吧。有八種吧。

哈哈哈O(∩_∩)O哈哈~????????????????

徹底暈菜????

oooO ↘┏━┓ ↙ Oooo

( 踩)→┃你┃ ←(死 )

\ ( →┃√┃ ← ) /

_)↗┗━┛ ↖(_/

來(lái)吧,直接告訴你結(jié)論吧。里面有幾個(gè)特例。

看上面這個(gè)表,所以如果想要同時(shí)做事情,當(dāng)然不能選同步任務(wù)啦。因?yàn)樗耆珱](méi)能力!搞不好還會(huì)造成鎖死。

要想同時(shí)做事情,就選concurrent Queue + 異步,或者global Queue + 異步。 不過(guò)人家global Queue本來(lái)就是concurrent Queue特殊的一種。

如果有多任務(wù),工作中最最省事兒常用的就是global Queue + 異步。單任務(wù)、刷新UI就用main Queue + 異步。

上面都沒(méi)心思看也沒(méi)關(guān)系。工作中,如果有多任務(wù),首選global Queue + 異步。單任務(wù)、刷新UI就用main Queue + 異步。

2. GCD的基礎(chǔ)應(yīng)用

我滴媽媽~經(jīng)過(guò)上面的分析,最后,最基礎(chǔ)的使用就兩種了。

多任務(wù):global Queue + 異步。

單任務(wù)、刷新UI就用main Queue + 異步。

說(shuō)實(shí)話,我也是第一次這么大膽的簡(jiǎn)化。會(huì)不會(huì)被大神們拍死?坐等~~~~

2.1 global Queue + 異步任務(wù)

/// global Queue + 異步任務(wù)
@IBAction func globalAsyn(_ sender: Any) {
    //創(chuàng)建一個(gè)全局隊(duì)列。
    //get a global queue
    let globalQueue = DispatchQueue.global()
    for i in 0...10 {
        
        //使用全局隊(duì)列,開(kāi)啟異步任務(wù)。
        //use the global queue , run in asynchronous
        globalQueue.async {
            print("I am No.\(i), current thread name is:\(Thread.current)")
        }
    }
}

我們看一下運(yùn)行的結(jié)果,亂序打印的,并且沒(méi)有在主線程中。這證明了確實(shí)是多個(gè)任務(wù)沒(méi)有按照順序執(zhí)行。

2.2 main Queue + 異步任務(wù)

/// main Queue + 異步任務(wù)
@IBAction func mainAsyn(_ sender: Any) {
    //創(chuàng)建一個(gè)主隊(duì)列
    //get a main queue
    let mainQueue = DispatchQueue.main
    
    for i in 0...10 {
        
        //使用主隊(duì)列,開(kāi)啟異步任務(wù)
        //use the main queue, run in asynchronous
        mainQueue.async {
            print("I am No.\(i), current thread name is:\(Thread.current)")
            
        }
    }
}

我們看一下運(yùn)行的結(jié)果,確實(shí)是順序打印的。并且都執(zhí)行在了主線程中。

2.3 小實(shí)踐:實(shí)現(xiàn)異步下載圖片

需求:異步下載一張圖片,下載完成后顯示在UI界面

實(shí)現(xiàn)后的效果圖:

思路:

  1. 在當(dāng)前UI動(dòng)作之外,開(kāi)啟一個(gè)global Queue+異步,用來(lái)下載圖片。因?yàn)檫^(guò)程可能很耗時(shí)。

  2. 等下載完成后,開(kāi)啟一個(gè)main Queue+異步,把下載的圖片賦值,刷新UI。

這個(gè)小Demo其實(shí)也實(shí)現(xiàn)了線程間通訊。

@IBAction func asynDownloadImage(_ sender: Any) {
    let imageVC = ImageVC()
    DispatchQueue.global().async {
        
        if let url = URL.init(string: "https://placebeard.it/355/140") {
            do {
                let imageData = try Data(contentsOf: url)
                let image = UIImage(data: imageData)
                
                
//因?yàn)檎旨揖W(wǎng)絡(luò)很好,為了模擬網(wǎng)絡(luò)很耗時(shí),就用了延時(shí)加載。
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(2), execute: {
                    imageVC.imageView.image = image
                    imageVC.imageView .sizeToFit()
                })
                
            } catch {
                print(error)
            }
        }
        
    }
    navigationController?.pushViewController(imageVC, animated: true)

}

3. GCD的服務(wù)質(zhì)量(優(yōu)先級(jí))

DispatchQoS.QoSClass是在Swift中封裝的關(guān)于描述服務(wù)質(zhì)量的類(lèi)。

這個(gè)在Operation里面也見(jiàn)到過(guò),級(jí)別越高,就會(huì)給分配的資源越多。但是并不是嚴(yán)格按照級(jí)別的高低來(lái)執(zhí)行的。

這是一個(gè)枚舉值:

public enum QoSClass {

    case background  //后臺(tái)默默執(zhí)行,The background quality of service class.
    case utility  //通用的,The utility quality of service class.

    case `default` //默認(rèn)值,The default quality of service class.


    case userInitiated  //用戶發(fā)起的,The user-initiated quality of service class.


    case userInteractive //用來(lái)執(zhí)行用戶交互,The user-interactive quality of service class.


    case unspecified //沒(méi)啥重要事情,The absence of a quality of service class.


    public init?(rawValue: qos_class_t)

    public var rawValue: qos_class_t { get }
}

看到上面的枚舉值,也大概能猜出來(lái)優(yōu)先級(jí)的高低了。和界面相關(guān)的、用戶的肯定是高的,后臺(tái)默默執(zhí)行的肯定是低的。

從高到低的順序分別是:userInteractive ->  userInitiated -> default ->  utility -> background -> unspecified

最基本的基礎(chǔ)基本上就到這里了。掂量了一下,還有調(diào)度組、信號(hào)量、阻塞等等都還沒(méi)寫(xiě)。這時(shí)候發(fā)現(xiàn)一篇寫(xiě)完GCD基礎(chǔ)貌似不太現(xiàn)實(shí),又不想一篇文章過(guò)長(zhǎng),那就拆開(kāi)吧。下次再說(shuō)。

  • iOS多線程系列之一:Operation基礎(chǔ)操作,按優(yōu)先級(jí)加載圖片

  • iOS多線程系列之二:Operation實(shí)例,異步加載CollectionView圖片

  • iOS多線程系列之三:使用GCD實(shí)現(xiàn)異步下載圖片

來(lái)自:http://www.jianshu.com/p/de4c990f64e9

 

標(biāo)簽: isp 代碼 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:從技巧、案例和工具入手,詳解性能優(yōu)化怎么做

下一篇:總結(jié)Android模塊化的一些知識(shí)點(diǎn)。