GCD方式的多線程

GCD方式的多線程

概念講解


//MARK: - 兩個(gè)概念:
//1.任務(wù): 想要執(zhí)行的操作(想要做的事情)
//2.隊(duì)列: 用來存儲(chǔ)任務(wù)的容器(先進(jìn)先出)

//GCD的使用步驟:
//1.創(chuàng)建隊(duì)列(需要確定隊(duì)列的類型)
//2.創(chuàng)建任務(wù),并且將任務(wù)添加到隊(duì)列中.(確定任務(wù)的執(zhí)行方式)
//GCD會(huì)自動(dòng)將任務(wù)從隊(duì)列中取出汉规,放到對應(yīng)的線程中去執(zhí)行

//MARK: - 四個(gè)術(shù)語
//任務(wù)的執(zhí)行方式:
//1.同步:在當(dāng)前線程中執(zhí)行(不會(huì)去創(chuàng)建新的線程)拉鹃,需要馬上執(zhí)行任務(wù)
//2.異步:在另外一個(gè)線程中執(zhí)行(會(huì)創(chuàng)建新的線程)

//隊(duì)列的類型:
//1.并發(fā):隊(duì)列中的任務(wù)可以同時(shí)執(zhí)行(前提是能有多個(gè)線程)
//2.串行:隊(duì)列中的任務(wù)一個(gè)一個(gè)順序執(zhí)行
class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //self.test1()
        self.test9()
    }
    
    
    //MARK: - 隊(duì)列組
    //隊(duì)列組的作用,解決問題:想要讓多個(gè)任務(wù)同時(shí)執(zhí)行,然后所有的任務(wù)全部執(zhí)行結(jié)束才回到主線程
    func test9() {
        
        //1.創(chuàng)建隊(duì)列組
        let group = dispatch_group_create()
        
        //2.將任務(wù)添加到隊(duì)列中,然后將隊(duì)列添加到隊(duì)列組
        //參數(shù)1:組
        //參數(shù)2:隊(duì)列
        //參數(shù)3:任務(wù)
        dispatch_group_async(group, dispatch_get_global_queue(0, 0)) { () -> Void in
            
            NSThread.sleepForTimeInterval(2)
            print("下載圖片A")
           
        }
         dispatch_group_async(group, dispatch_get_global_queue(0, 0)) { () -> Void in
            NSThread.sleepForTimeInterval(2)
            print("下載圖片B")
        }
        //3.當(dāng)group的隊(duì)列中的所有的任務(wù)都執(zhí)行完成后再回到主隊(duì)列
        //在指定組中的任務(wù)都完成以后膏燕,去執(zhí)行指定隊(duì)列中的指定任務(wù)
        //參數(shù)1:指定的隊(duì)列組
        //參數(shù)2:指定隊(duì)列
        //參數(shù)3:指定的任務(wù)
        dispatch_group_notify(group, dispatch_get_main_queue()) { () -> Void in
            
            print(NSThread.currentThread())
            print("回到主線程")
        }
    }
    
    
    
    //MARK: -!!! 線程間通信
    func test8() {
        
        //在子線程中去下載圖片
        dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
            print("下載:\(NSThread.currentThread())")
            //下載圖片
            let path = "http://i1.073img.com/160509/4230327_100603_1_lit.jpg"
            let url = NSURL.init(string: path)
            let data = NSData.init(contentsOfURL: url!)
            let image = UIImage.init(data: data!)
            
            //回到主線程中將圖片顯示出來(拿到主隊(duì)列)
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                
                print("顯示:\(NSThread.currentThread())")
                self.imageView.image = image
            })
        }
    }
    
    
    //MARK: - 主隊(duì)列
    //主隊(duì)列是在ios程序啟動(dòng)成功后系統(tǒng)自動(dòng)創(chuàng)建的一個(gè)和主線程關(guān)聯(lián)的隊(duì)列.在主隊(duì)列中的任務(wù)都是在主線程中執(zhí)行的钥屈。
    
    //2.同步執(zhí)行主隊(duì)列中的任務(wù)
    //結(jié)果:死鎖
    func test7() {
        
        for item in 0...10 {
            
            dispatch_sync(dispatch_get_main_queue(), { () -> Void in
                self.operationAction(item)
                
            })
        }
    }
    
    
    //1.異步執(zhí)行主隊(duì)列中的任務(wù)
    //結(jié)果: 在主線程中按順序執(zhí)行
    func test6() {
        
        //1.拿到主隊(duì)列
        let queue = dispatch_get_main_queue()
        //2.異步執(zhí)行
        for item in 0...10 {
            
            dispatch_async(queue, { () -> Void in
                self.operationAction(item)
            })
        }
    }
    
    
    
    //MARK: - 全局隊(duì)列
    //在ios進(jìn)程中,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)全局隊(duì)列坝辫,這個(gè)對列是并發(fā)的吨娜。目的是方便程序員快速的創(chuàng)建一個(gè)并發(fā)隊(duì)列
    //全局隊(duì)列:就是系統(tǒng)自動(dòng)創(chuàng)建的一個(gè)并發(fā)隊(duì)列埠戳,在使用的時(shí)候只需要獲取這個(gè)隊(duì)列
    //1.異步執(zhí)行全局隊(duì)列中的任務(wù)
    //結(jié)果:多個(gè)線程同時(shí)執(zhí)行多個(gè)任務(wù)
    func test5() {
        
        //1.獲取全局隊(duì)列(在整個(gè)進(jìn)程中只有一個(gè))
        //參數(shù)1:優(yōu)先級(不設(shè)置)
        //參數(shù)2:預(yù)留參數(shù)
        let queue = dispatch_get_global_queue(0, 0)
        //將任務(wù)添加到全局隊(duì)列中,異步執(zhí)行
        for item in 0...10 {
            
            dispatch_async(queue, { () -> Void in
                self.operationAction(item)
            })
        }
        print("結(jié)束")
    }
    
    
    //MARK: - 基本運(yùn)用
    
    
    //4.異步并行
    //異步:在另外的線程中執(zhí)行
    //并發(fā):多個(gè)任務(wù)同時(shí)執(zhí)行
    //結(jié)果:多個(gè)線程中,多個(gè)任務(wù)同時(shí)執(zhí)行
    
    func test4() {
        
        //1.創(chuàng)建并發(fā)隊(duì)列
        let queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT)
        //2.將任務(wù)添加到隊(duì)列中盾饮,異步執(zhí)行
        for item in 0...10 {
            
            dispatch_async(queue, { () -> Void in
                self.operationAction(item)
            })
        }
        print("結(jié)束")
    }
    
    //3.異步串行
    //異步:在另外的線程中執(zhí)行
    //串行:按順序一個(gè)一個(gè)的執(zhí)行
    //結(jié)果:在一個(gè)子線程中按順序一個(gè)一個(gè)的執(zhí)行沐兰,先打印"結(jié)束"趋翻,再執(zhí)行任務(wù)
    
    func test3() {
        //1.創(chuàng)建串行隊(duì)列
        let queue = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL)
        //2.將任務(wù)添加到隊(duì)列中芹壕,異步執(zhí)行
        for item in 0...10 {
            
            dispatch_async(queue, { () -> Void in
                self.operationAction(item)
            })
        }
        print("結(jié)束")
    }
    
    
    
    
    
    //2.同步并行
    //同步:在當(dāng)前線程中執(zhí)行(不會(huì)開新的線程)
    //并行:多個(gè)任務(wù)同時(shí)執(zhí)行(前提:的有多個(gè)線程)
    //結(jié)果:在主線程中,按順序一個(gè)一個(gè)的執(zhí)行;先執(zhí)行任務(wù)再打印的"結(jié)束"
    func test2() {
        
        //1. 創(chuàng)建并行對列
        //DISPATCH_QUEUE_CONCURRENT ->并行
        let queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT)
        //2.將任務(wù)添加到隊(duì)列中锯玛,同步執(zhí)行
        for item in 0...10 {
            
            dispatch_sync(queue, { () -> Void in
                self.operationAction(item)
            })
        }
        print("結(jié)束")
    }
    
    //1.同步串行
    //同步:在當(dāng)前線程中執(zhí)行
    //串行:一個(gè)一個(gè)按順序執(zhí)行
    //結(jié)果:在主線程中按順序執(zhí)行;先執(zhí)行任務(wù)再打印的"結(jié)束"
   
    func test1() {
        //1.創(chuàng)建隊(duì)列變量
        //參數(shù)1:隊(duì)列的標(biāo)簽咐柜,用來區(qū)分不同的隊(duì)列;(c字符串類型)
        //參數(shù)2:隊(duì)列屬性(類型),要么是串行要么是并行
        //DISPATCH_QUEUE_SERIAL -> 串行
        let queue = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL)
        //2.將指定的任務(wù)添加到指定的隊(duì)列中攘残,并且確定任務(wù)的執(zhí)行方式是同步執(zhí)行
        //參數(shù)1:指定的隊(duì)列
        //參數(shù)2:指定的任務(wù)
        dispatch_sync(queue) { () -> Void in
            self.operationAction(0)
        }
        
        //3.在隊(duì)列中添加多個(gè)任務(wù)
        for item in 1...10 {
            
            dispatch_sync(queue, { () -> Void in
                self.operationAction(item)
            })
        }
        print("結(jié)束")
    }
    
    //MARK: - 操作
    func operationAction(i: Int) {
        
        print(NSThread.currentThread(),i)
    }
    
}

NSOperation方式實(shí)現(xiàn)多線程

//MARK: - 兩個(gè)核心概念
//1.任務(wù)(操作)(NSOperation):確定要做的事情 -> 需要封裝成一個(gè)任務(wù)/操作對象
//2.隊(duì)列(NSOperationQueue):用來存放任務(wù)的容器

//使用NSOperation和NSOperationqueue實(shí)現(xiàn)多線程的步驟:
//1.創(chuàng)建任務(wù)對象
//2.創(chuàng)建隊(duì)列對象
//3.將任務(wù)添加到隊(duì)列
//系統(tǒng)會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出來放到一個(gè)新的線程中執(zhí)行

class ViewController: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    //MARK: - 屬性
    
    lazy var queue: NSOperationQueue = {
      
        
        return NSOperationQueue()
    }()
    
    //MARK: - UITouch
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.test5()
    }
    
    //MARK: - 高級應(yīng)用
    
    //4.依賴關(guān)系
    //解決的問題:如果要求必須是任務(wù)A執(zhí)行完成后才能執(zhí)行任務(wù)B拙友,那么就可以讓任務(wù)B去依賴任務(wù)A
    func test5() {
        
        //1.創(chuàng)建任務(wù)
        //任務(wù)A
        let operationA = NSBlockOperation.init { () -> Void in
            
            NSThread.sleepForTimeInterval(1)
            print("登錄成功")
        }
        //任務(wù)B
        let operationB = NSBlockOperation.init { () -> Void in
            NSThread.sleepForTimeInterval(1)
            print("下載電影")
        }
        //任務(wù)C
        let operationC = NSBlockOperation.init { () -> Void in
            NSThread.sleepForTimeInterval(1)
            print("顯示廣告")
        }
        
        //2.建立依賴關(guān)系
        //注意: a.任務(wù)之間的依賴關(guān)系一定要在任務(wù)被添加到隊(duì)列中之前建立,否則無效 b.依賴關(guān)系不可以形成循環(huán)
        //讓任務(wù)B歼郭,依賴任務(wù)A(任務(wù)A執(zhí)行結(jié)束后才會(huì)執(zhí)行任務(wù)B)
        operationB.addDependency(operationA)
        
        //3.在隊(duì)列中同時(shí)添加多個(gè)任務(wù)
        self.queue.addOperations([operationA,operationB,operationC], waitUntilFinished: false)
    }
    
    //3. 隊(duì)列的取消
    //隊(duì)列的取消:指的是調(diào)用cancelAllOperation的方法的瞬間遗契,銷毀隊(duì)列中所有的任務(wù)。如果任務(wù)已經(jīng)從隊(duì)列中取出來了病曾,就不能被這個(gè)方法銷毀牍蜂。如果隊(duì)列已經(jīng)取消,那么銷毀的隊(duì)列中的任務(wù)就不能再復(fù)原泰涂。
    @IBAction func btnAction1(sender: AnyObject) {
        
        self.queue.cancelAllOperations()
    }
    
    
    //2. 隊(duì)列的掛起和取消(暫停和取消暫停)
    //隊(duì)列的暫停:指的是暫停從隊(duì)列中取出任務(wù)鲫竞,但是已經(jīng)從隊(duì)列中取出來的任務(wù)任然會(huì)繼續(xù)執(zhí)行
    @IBAction func btnAction(sender: UIButton) {
        
        if sender.currentTitle == "暫停" {
            
            //1.暫停隊(duì)列
            self.queue.suspended = true
            
            sender.setTitle("繼續(xù)", forState: .Normal)
        }
        else {
            //2.取消暫停
            self.queue.suspended = false
            sender.setTitle("暫停", forState: .Normal)
        }
    }
    
    //1.最大并發(fā)數(shù)
    func test4() {
        
        //1.設(shè)置最大并發(fā)數(shù)(設(shè)置同一時(shí)刻同時(shí)能夠執(zhí)行的最多的任務(wù)的個(gè)數(shù))
        self.queue.maxConcurrentOperationCount = 3
       
        //2.添加任務(wù)
        for item in 0...30 {
            
            self.queue.addOperationWithBlock({ () -> Void in
                
                self.longTimeOperation(item)
            })
        }
    }
    
    
    //MARK: - !!!線程間通信
    func  test3() {
        
        //1.去子線程中下載圖片
        self.queue.addOperationWithBlock { () -> Void in
            
            let data = NSData.init(contentsOfURL: NSURL.init(string: "http://i1.073img.com/160509/4230327_100603_1_lit.jpg")!)
            let image = UIImage.init(data: data!) 
            
            //2.回到主線程去顯示圖片(將任務(wù)添加到主隊(duì)列中)
            //強(qiáng)調(diào):所有的UI操作必須在主線程中執(zhí)行
            NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                //顯示圖片
                self.imageView.image = image
            })
        }
    }
    
    
    
    //MARK: - 基本使用
    
    //2.快速的在隊(duì)列中添加任務(wù)
    func test2() {
        //向隊(duì)列中添加任務(wù)
        for item in 0...10 {
            
            self.queue.addOperationWithBlock { () -> Void in
                self.longTimeOperation(item)
            }

        }
    }
    
    
    func test1() {
        
        //1.創(chuàng)建隊(duì)列對象
        let queue = NSOperationQueue.init()
        
        //2.創(chuàng)建任務(wù)對象
        let operation = NSBlockOperation.init { () -> Void in
            
            self.longTimeOperation(0)
        }
        
        //3.將任務(wù)添加到隊(duì)列中
        queue.addOperation(operation)
        
        //4.在隊(duì)列中天再添加多個(gè)任務(wù)
        for item in 1...10 {
            
            let operation2 = NSBlockOperation.init(block: { () -> Void in
                self.longTimeOperation(item)
            })
            queue.addOperation(operation2)
        }
        
    }
    
    //MARK: - 操作
    func longTimeOperation(i: Int) {
        
        NSThread.sleepForTimeInterval(1)
        print(NSThread.currentThread(),i)
    }
    
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市负敏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秘蛇,老刑警劉巖其做,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赁还,居然都是意外死亡妖泄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門艘策,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹈胡,“玉大人,你說我怎么就攤上這事》=ィ” “怎么了却汉?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荷并。 經(jīng)常有香客問我合砂,道長,這世上最難降的妖魔是什么源织? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任翩伪,我火速辦了婚禮,結(jié)果婚禮上谈息,老公的妹妹穿的比我還像新娘缘屹。我一直安慰自己,他們只是感情好侠仇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布轻姿。 她就那樣靜靜地躺著,像睡著了一般傅瞻。 火紅的嫁衣襯著肌膚如雪踢代。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天嗅骄,我揣著相機(jī)與錄音胳挎,去河邊找鬼。 笑死溺森,一個(gè)胖子當(dāng)著我的面吹牛慕爬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屏积,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼医窿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炊林?” 一聲冷哼從身側(cè)響起姥卢,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渣聚,沒想到半個(gè)月后独榴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奕枝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年棺榔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隘道。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡症歇,死狀恐怖郎笆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情忘晤,我是刑警寧澤宛蚓,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站德频,受9級特大地震影響苍息,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜壹置,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一竞思、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钞护,春花似錦盖喷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至余佃,卻和暖如春暮刃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爆土。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工椭懊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人步势。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓氧猬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親坏瘩。 傳聞我的和親對象是個(gè)殘疾皇子盅抚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容