GCD方式的多线程
概念讲解
//MARK: - 两个概念:
//1.任务: 想要执行的操作(想要做的事情)
//2.队列: 用来存储任务的容器(先进先出)
//GCD的使用步骤:
//1.创建队列(需要确定队列的类型)
//2.创建任务,并且将任务添加到队列中.(确定任务的执行方式)
//GCD会自动将任务从队列中取出,放到对应的线程中去执行
//MARK: - 四个术语
//任务的执行方式:
//1.同步:在当前线程中执行(不会去创建新的线程),需要马上执行任务
//2.异步:在另外一个线程中执行(会创建新的线程)
//队列的类型:
//1.并发:队列中的任务可以同时执行(前提是能有多个线程)
//2.串行:队列中的任务一个一个顺序执行
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//self.test1()
self.test9()
}
//MARK: - 队列组
//队列组的作用,解决问题:想要让多个任务同时执行,然后所有的任务全部执行结束才回到主线程
func test9() {
//1.创建队列组
let group = dispatch_group_create()
//2.将任务添加到队列中,然后将队列添加到队列组
//参数1:组
//参数2:队列
//参数3:任务
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.当group的队列中的所有的任务都执行完成后再回到主队列
//在指定组中的任务都完成以后,去执行指定队列中的指定任务
//参数1:指定的队列组
//参数2:指定队列
//参数3:指定的任务
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!)
//回到主线程中将图片显示出来(拿到主队列)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("显示:\(NSThread.currentThread())")
self.imageView.image = image
})
}
}
//MARK: - 主队列
//主队列是在ios程序启动成功后系统自动创建的一个和主线程关联的队列.在主队列中的任务都是在主线程中执行的。
//2.同步执行主队列中的任务
//结果:死锁
func test7() {
for item in 0...10 {
dispatch_sync(dispatch_get_main_queue(), { () -> Void in
self.operationAction(item)
})
}
}
//1.异步执行主队列中的任务
//结果: 在主线程中按顺序执行
func test6() {
//1.拿到主队列
let queue = dispatch_get_main_queue()
//2.异步执行
for item in 0...10 {
dispatch_async(queue, { () -> Void in
self.operationAction(item)
})
}
}
//MARK: - 全局队列
//在ios进程中,系统会自动创建一个全局队列,这个对列是并发的。目的是方便程序员快速的创建一个并发队列
//全局队列:就是系统自动创建的一个并发队列,在使用的时候只需要获取这个队列
//1.异步执行全局队列中的任务
//结果:多个线程同时执行多个任务
func test5() {
//1.获取全局队列(在整个进程中只有一个)
//参数1:优先级(不设置)
//参数2:预留参数
let queue = dispatch_get_global_queue(0, 0)
//将任务添加到全局队列中,异步执行
for item in 0...10 {
dispatch_async(queue, { () -> Void in
self.operationAction(item)
})
}
print("结束")
}
//MARK: - 基本运用
//4.异步并行
//异步:在另外的线程中执行
//并发:多个任务同时执行
//结果:多个线程中,多个任务同时执行
func test4() {
//1.创建并发队列
let queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT)
//2.将任务添加到队列中,异步执行
for item in 0...10 {
dispatch_async(queue, { () -> Void in
self.operationAction(item)
})
}
print("结束")
}
//3.异步串行
//异步:在另外的线程中执行
//串行:按顺序一个一个的执行
//结果:在一个子线程中按顺序一个一个的执行,先打印"结束",再执行任务
func test3() {
//1.创建串行队列
let queue = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL)
//2.将任务添加到队列中,异步执行
for item in 0...10 {
dispatch_async(queue, { () -> Void in
self.operationAction(item)
})
}
print("结束")
}
//2.同步并行
//同步:在当前线程中执行(不会开新的线程)
//并行:多个任务同时执行(前提:的有多个线程)
//结果:在主线程中,按顺序一个一个的执行;先执行任务再打印的"结束"
func test2() {
//1. 创建并行对列
//DISPATCH_QUEUE_CONCURRENT ->并行
let queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT)
//2.将任务添加到队列中,同步执行
for item in 0...10 {
dispatch_sync(queue, { () -> Void in
self.operationAction(item)
})
}
print("结束")
}
//1.同步串行
//同步:在当前线程中执行
//串行:一个一个按顺序执行
//结果:在主线程中按顺序执行;先执行任务再打印的"结束"
func test1() {
//1.创建队列变量
//参数1:队列的标签,用来区分不同的队列;(c字符串类型)
//参数2:队列属性(类型),要么是串行要么是并行
//DISPATCH_QUEUE_SERIAL -> 串行
let queue = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL)
//2.将指定的任务添加到指定的队列中,并且确定任务的执行方式是同步执行
//参数1:指定的队列
//参数2:指定的任务
dispatch_sync(queue) { () -> Void in
self.operationAction(0)
}
//3.在队列中添加多个任务
for item in 1...10 {
dispatch_sync(queue, { () -> Void in
self.operationAction(item)
})
}
print("结束")
}
//MARK: - 操作
func operationAction(i: Int) {
print(NSThread.currentThread(),i)
}
}
NSOperation方式实现多线程
//MARK: - 两个核心概念
//1.任务(操作)(NSOperation):确定要做的事情 -> 需要封装成一个任务/操作对象
//2.队列(NSOperationQueue):用来存放任务的容器
//使用NSOperation和NSOperationqueue实现多线程的步骤:
//1.创建任务对象
//2.创建队列对象
//3.将任务添加到队列
//系统会自动将队列中的任务取出来放到一个新的线程中执行
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: - 高级应用
//4.依赖关系
//解决的问题:如果要求必须是任务A执行完成后才能执行任务B,那么就可以让任务B去依赖任务A
func test5() {
//1.创建任务
//任务A
let operationA = NSBlockOperation.init { () -> Void in
NSThread.sleepForTimeInterval(1)
print("登录成功")
}
//任务B
let operationB = NSBlockOperation.init { () -> Void in
NSThread.sleepForTimeInterval(1)
print("下载电影")
}
//任务C
let operationC = NSBlockOperation.init { () -> Void in
NSThread.sleepForTimeInterval(1)
print("显示广告")
}
//2.建立依赖关系
//注意: a.任务之间的依赖关系一定要在任务被添加到队列中之前建立,否则无效 b.依赖关系不可以形成循环
//让任务B,依赖任务A(任务A执行结束后才会执行任务B)
operationB.addDependency(operationA)
//3.在队列中同时添加多个任务
self.queue.addOperations([operationA,operationB,operationC], waitUntilFinished: false)
}
//3. 队列的取消
//队列的取消:指的是调用cancelAllOperation的方法的瞬间,销毁队列中所有的任务。如果任务已经从队列中取出来了,就不能被这个方法销毁。如果队列已经取消,那么销毁的队列中的任务就不能再复原。
@IBAction func btnAction1(sender: AnyObject) {
self.queue.cancelAllOperations()
}
//2. 队列的挂起和取消(暂停和取消暂停)
//队列的暂停:指的是暂停从队列中取出任务,但是已经从队列中取出来的任务任然会继续执行
@IBAction func btnAction(sender: UIButton) {
if sender.currentTitle == "暂停" {
//1.暂停队列
self.queue.suspended = true
sender.setTitle("继续", forState: .Normal)
}
else {
//2.取消暂停
self.queue.suspended = false
sender.setTitle("暂停", forState: .Normal)
}
}
//1.最大并发数
func test4() {
//1.设置最大并发数(设置同一时刻同时能够执行的最多的任务的个数)
self.queue.maxConcurrentOperationCount = 3
//2.添加任务
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.回到主线程去显示图片(将任务添加到主队列中)
//强调:所有的UI操作必须在主线程中执行
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
//显示图片
self.imageView.image = image
})
}
}
//MARK: - 基本使用
//2.快速的在队列中添加任务
func test2() {
//向队列中添加任务
for item in 0...10 {
self.queue.addOperationWithBlock { () -> Void in
self.longTimeOperation(item)
}
}
}
func test1() {
//1.创建队列对象
let queue = NSOperationQueue.init()
//2.创建任务对象
let operation = NSBlockOperation.init { () -> Void in
self.longTimeOperation(0)
}
//3.将任务添加到队列中
queue.addOperation(operation)
//4.在队列中天再添加多个任务
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)
}
}