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)系作者