ios多线程
来源:互联网 发布:python 首字母小写 编辑:程序博客网 时间:2024/06/08 14:04
关于多线程处理,很多人不敢用,因为多线程常常会导致一些奇葩的问题出现(大多都是资源共享导致的)。但存在肯定是有其道理的,如果你对它足够了解,当然也不一定就不出问题。起码是出了问题很快就可以定位到。至于多线程的优势,我想不说大家也都知道,肯定是比单线程要快的。这里就讲讲iOS的多线程并发处理。现在的设备很少是单核处理器了,如果你还用单线程,那可真是暴殄天物啊。那么多资源就被你这样浪费了。在iOS中主线程是处理UI的,你如果什么都在主线程里操作,这样用户的体验会非常的差,因为操作一个事件就要等其结束才能继续。所以用户体验很差,今天就来谈谈iOS的多线程处理。
第一部分:GCD
GCD是管理多线程最常用的api,GCD提供并管理任务队列。当然首先要了解队列是什么东西。
队列是管理对象的先进先出(FIFO)的一种数据结构,就像排队买票,排在前面的先买,后面的后买一样。
- DISPATCH_QUEUE_PRIORITY_HIGH
- DISPATCH_QUEUE_PRIORITY_DEFAULT
- DISPATCH_QUEUE_PRIORITY_LOW
- DISPATCH_QUEUE_PRIORITY_BACKGROUND
- 当然,他们的优先级从上到下越来越低的是。你可以使用任意一个你想用的队列,但是请注意,这些队列是系统提供给你的,所以队列里面的任务不一定都是你的任务(可能有其他的任务)。
<span style="font-size:14px;">@IBActionfuncdidClickOnStart(sender:AnyObject){ letimg1=Downloader.downloadImageWithURL(imageURLs[0]) self.imageView1.image=img1 letimg2=Downloader.downloadImageWithURL(imageURLs[1]) self.imageView2.image=img2 letimg3=Downloader.downloadImageWithURL(imageURLs[2]) self.imageView3.image=img3 letimg4=Downloader.downloadImageWithURL(imageURLs[3]) self.imageView4.image=img4 }</span>
<span style="font-size:14px;">letqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0) dispatch_async(queue){()->Voidin letimg1=Downloader.downloadImageWithURL(imageURLs[0]) dispatch_async(dispatch_get_main_queue(),{ self.imageView1.image=img1 }) }</span>
<span style="font-size:14px;">@IBActionfuncdidClickOnStart(sender:AnyObject){ letqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0) dispatch_async(queue){()->Voidin letimg1=Downloader.downloadImageWithURL(imageURLs[0]) dispatch_async(dispatch_get_main_queue(),{ self.imageView1.image=img1 }) } dispatch_async(queue){()->Voidin letimg2=Downloader.downloadImageWithURL(imageURLs[1]) dispatch_async(dispatch_get_main_queue(),{ self.imageView2.image=img2 }) } dispatch_async(queue){()->Voidin letimg3=Downloader.downloadImageWithURL(imageURLs[2]) dispatch_async(dispatch_get_main_queue(),{ self.imageView3.image=img3 }) } dispatch_async(queue){()->Voidin letimg4=Downloader.downloadImageWithURL(imageURLs[3]) dispatch_async(dispatch_get_main_queue(),{ self.imageView4.image=img4 }) } }</span>
<span style="font-size:14px;">@IBActionfuncdidClickOnStart(sender:AnyObject){ letserialQueue=dispatch_queue_create("com.appcoda.imagesQueue",DISPATCH_QUEUE_SERIAL) dispatch_async(serialQueue){()->Voidin letimg1=Downloader.downloadImageWithURL(imageURLs[0]) dispatch_async(dispatch_get_main_queue(),{ self.imageView1.image=img1 }) } dispatch_async(serialQueue){()->Voidin letimg2=Downloader.downloadImageWithURL(imageURLs[1]) dispatch_async(dispatch_get_main_queue(),{ self.imageView2.image=img2 }) } dispatch_async(serialQueue){()->Voidin letimg3=Downloader.downloadImageWithURL(imageURLs[2]) dispatch_async(dispatch_get_main_queue(),{ self.imageView3.image=img3 }) } dispatch_async(serialQueue){()->Voidin letimg4=Downloader.downloadImageWithURL(imageURLs[3]) dispatch_async(dispatch_get_main_queue(),{ self.imageView4.image=img4 }) } }</span>
NSOperation
1、支持依赖
2、改变执行的优先级
<span style="font-size:14px;">publicenumNSOperationQueuePriority: Int{ caseVeryLow caseLow caseNormal caseHigh caseVeryHigh}</span>
3、对于任何给定的队列,你可以取消操作,当任务被加到队列中后,你可以调用NSOperation实例对象的cancel()方法来取消这个任务。但取消操作有如下三种情形可能:
任务已经执行完,取消则无效果。
任务正在被执行,如果那样,系统不会强制停止任务,但取消的属性(cancelled)将被置为真。
任务在队列等待执行,那么它将被取消。
4、NSOperation有三个有用的布尔值属性finished, cancelled, and ready。finished 将被置为真当任务完成的时候,cancelled将为真当任务被取消的时候,ready将被置为真,当其可以被执行的时候。
5、任何的NSOperation都有一个选项设置完成后的block,当任务被完成后调用,也就是当finished属性被赋值为真之后,block开始执行。
接下来我们重写上面的demo用NSOperationQueues,首先声明变量在ViewController中
varqueue=NSOperationQueue()
然后重写这个方法didClickOnStart
<span style="font-size:14px;">@IBActionfuncdidClickOnStart(sender:AnyObject){ queue=NSOperationQueue() queue.addOperationWithBlock{()->Voidin letimg1=Downloader.downloadImageWithURL(imageURLs[0]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView1.image=img1 }) } queue.addOperationWithBlock{()->Voidin letimg2=Downloader.downloadImageWithURL(imageURLs[1]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView2.image=img2 }) } queue.addOperationWithBlock{()->Voidin letimg3=Downloader.downloadImageWithURL(imageURLs[2]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView3.image=img3 }) } queue.addOperationWithBlock{()->Voidin letimg4=Downloader.downloadImageWithURL(imageURLs[3]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView4.image=img4 }) }}</span>
上面用了addOperationWithBlock这个方法,接下来我们加入了回调block重新处理下
<span style="font-size:14px;">@IBAction func didClickOnStart(sender: AnyObject) { queue = NSOperationQueue() let operation1 = NSBlockOperation(block: { let img1 = Downloader.downloadImageWithURL(imageURLs[0]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView1.image = img1 }) }) operation1.completionBlock = { print("Operation 1 completed") } queue.addOperation(operation1) let operation2 = NSBlockOperation(block: { let img2 = Downloader.downloadImageWithURL(imageURLs[1]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView2.image = img2 }) }) operation2.completionBlock = { print("Operation 2 completed") } queue.addOperation(operation2) let operation3 = NSBlockOperation(block: { let img3 = Downloader.downloadImageWithURL(imageURLs[2]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView3.image = img3 }) }) operation3.completionBlock = { print("Operation 3 completed") } queue.addOperation(operation3) let operation4 = NSBlockOperation(block: { let img4 = Downloader.downloadImageWithURL(imageURLs[3]) NSOperationQueue.mainQueue().addOperationWithBlock({ self.imageView4.image = img4 }) }) operation4.completionBlock = { print("Operation 4 completed") } queue.addOperation(operation4)}</span>取消的操作
为了验证取消操作,我们在导航栏上加了取消按钮。假设我们有四个任务,#3依赖#2,#2依赖任务#1,#4没有依赖。
下面是取消部分代码
<span style="font-size:14px;">@IBAction func didClickOnCancel(sender: AnyObject) { self.queue.cancelAllOperations() }</span>
这个需要关联取消按钮的,并且在这个方法didClickOnStart中加入如下两行代码:
<span style="font-size:14px;">operation2.addDependency(operation1)operation3.addDependency(operation2)</span>
然后改变回调方法,加上日志
<span style="font-size:14px;">operation1.completionBlock = { print("Operation 1 completed, cancelled:\(operation1.cancelled) ") }</span>
其他几个类似这样的。
点开始按钮之后,再迅速按取消,结果如下:
#1已经开始了,所以取消没有任何结果,但#2和#3都依赖于#1,所以#2和#3都被取消了,但#4没有任何关联,则和#1一起执行了。效果图如下:
水平有限,有机会再回来修改。
- ios多线程
- iOS多线程
- iOS多线程
- iOS多线程
- 多线程ios
- IOS 多线程
- ios多线程
- ios 多线程
- IOS多线程
- IOS多线程
- iOS多线程
- iOS多线程
- ios 多线程
- iOS多线程
- IOS多线程
- ios多线程
- iOS 多线程
- iOS 多线程
- Notification的功能和用法
- linux 后台任务,screen命令
- Eclipse设置
- sql时间戳按时间进行分组
- linux常用命令
- ios多线程
- java提高篇(四)-----抽象类与接口
- com/opensymphony/xwork2/spring/SpringObjectFactory.java:220:-1问题出现的原因及解决办法
- numpy 基础知识
- Wix学习整理(2)——HelloWorld安装添加UI
- UIPageViewController 专辑
- 第13周项目2-Kruskal算法的验证
- hdu1085 Holding Bin-Laden Captive! (多重背包)
- putty(ssh)无法登陆linux(bt5)解决方案