IOS多线程编程中,GCD是一个很方便的库,它的核心是GCD队列,所有操作都围绕着队列。
1、GCD中的三种队列
GCD中三种队列:主队列、全局队列、自定义队列。
//创建一个全局队列,队列的优先级(Priority)为Default,第二个参数暂时保留,传0即可 let myQueue: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //创建一个自定义队列,第一个参数是队列的标识名字,第二个参数指定队列是并发队列(concurrent),如果是串行队列的话是serial let myQueue2: dispatch_queue_t = dispatch_queue_create("队列标识字符串", DISPATCH_QUEUE_CONCURRENT) //获取当前主队列 let myQueue3: dispatch_queue_t = dispatch_get_main_queue()
2、串行队列和并发队列
在使用自定义队列时,需要指定队列是并发的还是串行的,使用并发的居多,参数是:
//串行队列 DISPATCH_QUEUE_SERIAL //并发队列 DISPATCH_QUEUE_CONCURRENT
3、队列的优先级
在创建全局队列时,需要指定队列的优先级,一共有4种级别:
//优先级从低到高,一般使用Default即可 DISPATCH_QUEUE_PRIORITY_BACKGROUND DISPATCH_QUEUE_PRIORITY_LOW DISPATCH_QUEUE_PRIORITY_DEFAULT DISPATCH_QUEUE_PRIORITY_HIGH
4、使用异步方法执行队列
//使用异步方式运行调用队列,主程序遇到后会继续执行后面的代码 dispatch_async(myQueue){ //队列中需要执行的任务 self.setLabel() }
5、在主队列中更新UI
多线程编程时,一定要在主线程也就是主队列中更新UI,所以凡是需要修改界面内容都要在main_queue中操作
//在主线程中更新UI控件 dispatch_async(dispatch_get_main_queue()){ self.lblString.text = "更新的内容" }
6、队列延迟
使用dispatch_after可以延迟一段时间执行队列中的任务。
//队列延迟2秒执行 let time:dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, (Int64)(NSEC_PER_SEC * 2)) dispatch_after(time, dispatch_get_main_queue()) { self.lblString.text = "队列延迟操作了" }
第一个参数是dispatch_time_t,作为一个时间对象,在dispatch_time中有两种时间模式:
DISPATCH_TIME_FOREVER DISPATCH_TIME_NOW
7、队列重复(循环)
//队列的重复,循环3次,放在并发的全局队列中,闭包中有一个参数,包含了当前循环次数的索引值 dispatch_apply(3, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { println($0) }
8、使用Group调度组来管理队列,基于notify来回调事件方法
//自定义的队列 var myQueue: dispatch_queue_t? override func viewDidLoad() { super.viewDidLoad() self.myQueue = dispatch_queue_create("lijialong.thread", DISPATCH_QUEUE_CONCURRENT) } //使用调度组对任务管理,完成后使用notify回调更新Label private func use_Dispatch_Group_AsyncNotify(){ //创建一个调度组 var myGroup = dispatch_group_create() //使用自定义队列,异步调度组 dispatch_group_async(myGroup, myQueue!){ var data1 = NSData(contentsOfURL: NSURL(string: "hhttp://b.hiphotos.baidu.com/image/w%3D310/sign=e22578ddd462853592e0d420a0ee76f2/b03533fa828ba61ed1a6ca004034970a304e5950.jpg")!) self.updateImageData(imgView: self.img1, data: data1!) } dispatch_group_async(myGroup, myQueue!){ var data2 = NSData(contentsOfURL: NSURL(string: "http://e.hiphotos.baidu.com/image/w%3D310/sign=19025f7e9058d109c4e3afb3e158ccd0/fd039245d688d43f43c2adf27f1ed21b0ef43b42.jpg")!) self.updateImageData(imgView: self.img2, data: data2!) } dispatch_group_notify(myGroup, dispatch_get_main_queue()){ self.lbl.text = "Load Finish" } } //在主线程中更新UI private func updateImageData(#imgView:UIImageView,data:NSData){ dispatch_async(dispatch_get_main_queue()){ imgView.image = UIImage(data: data) } }
9、使用Group调度组管理队列,基于wait来等待执行完成,会阻塞主线程
private func use_Dispatch_Group_Wait(){ var myGroup = dispatch_group_create() dispatch_group_async(myGroup, myQueue!){ var data1 = NSData(contentsOfURL: NSURL(string: "hhttp://b.hiphotos.baidu.com/image/w%3D310/sign=e22578ddd462853592e0d420a0ee76f2/b03533fa828ba61ed1a6ca004034970a304e5950.jpg")!) self.updateImageData(imgView: self.img1, data: data1!) } dispatch_group_async(myGroup, myQueue!){ var data2 = NSData(contentsOfURL: NSURL(string: "http://e.hiphotos.baidu.com/image/w%3D310/sign=19025f7e9058d109c4e3afb3e158ccd0/fd039245d688d43f43c2adf27f1ed21b0ef43b42.jpg")!) self.updateImageData(imgView: self.img2, data: data2!) } //等待group完成后,再运行后面,会阻塞主线程! dispatch_group_wait(myGroup, DISPATCH_TIME_FOREVER) lbl.text = "Load Finish" }
10、队列暂停与恢复
//暂停 只能对自定义队列操作,不能对主线程和全局队列操作 // 只能暂停还未加载到队列中的任务,已经加载的无法暂停,可以使用dispatch_after延迟队列解决 private func suspend(){ dispatch_suspend(myQueue!) } //恢复 private func resume(){ dispatch_resume(myQueue!) }