MyException - 我的异常网
当前位置:我的异常网» Iphone » 多线程:Operation(1)

多线程:Operation(1)

www.MyException.Cn  网友分享于:2013-11-02  浏览:0次
多线程:Operation(一)

1. 进程和线程

1.1 进程

  • 进程:正在运行的应用程序叫进程
  • 进程之间都是独立的,运行在专用且受保护的内存空间中
  • 两个进程之间无法通讯

通俗的理解,手机上同时开启了两个App。这两个App肯定是在不同的进程中的。所以这两个App之间是独立的,内存中的数据不能互相窜来窜去,两个App之间也没有办法进行通讯。

两个App之间没有办法进行通讯?我说的是正常情况下。当然还是有不正常情况啊,例如使用iOS提供的极少数的几种进程间通讯的工具。

1.2 线程

  • 线程:进程想要执行任务,必须要有线程,每个进程至少有一条线程。
  • 线程就是用来干活的。
  • 程序一启动,就会启动进程。进程默认开启一条线程。

干活的线程?对啊,活太多,或者不想彼此互相等着浪费时间,当然可以找几个人同时干了。
例如在项目上,产品经理需求都没有完全写完,也不妨碍先设计一个大概的数据框架啊。例如需求没有完全定下来,不妨碍UI童鞋提前设计啊,大不了再改嘛~ HOHO~怎么听上去都像是黑话。

1.3 多线程

  • 单核CPU同一时间,CPU只能处理1个线程,只有1个线程在执行任务。

  • 多线程的同时执行 : 其实是CPU在多条线程之间快速切换(调度任务)。

  • 如果CPU调度线程的速度足够快,就造成了多线程同时执行的假象

  • 如果线程非常多,CPU会在多条线程之间不断的调度任务,结果就是消耗了大量的CPU资源,效率下降:

    • 每个线程调度的频率会降低
    • 线程的执行效率会下降

iPhone手机是几核的?
A7 : iPhone 5S , 双核
A8: iPhone 6、iPhone 6 Plus,双核
A9:iPhone 6S、iPhone 6S Plus,双核
A10:iPhone 7、iPhone 7 Plus,2+2核

1.4 iOS中的多线程

刚才说了,iOS App一旦运行,默认就会开启一条线程。这条线程,我们通常称作为“主线程

主线程的作用:

  1. 刷新UI
  2. 处理UI事件,例如点击、滚动、拖拽。

如果主线程的操作太多、太耗时,就会造成App卡顿现象严重。所以,通常我们都会把耗时的操作放在子线程中进行,获取到结果之后,回到主线程去刷新UI。

2. Operation

 

我们来看看基础使用:

 1 //    最基本的使用Operation
 2     private func basicOperation() {
 3 //        第一步:创建Operation
 4         let op = Operation.init()
 5 //        第二步:把要执行的代码放入operation中
 6         op.completionBlock = {
 7         
 8             print(#function,#line,Thread.current)
 9         }
10 //        第三步:创建OperationQueue
11         let opQueue = OperationQueue.init()
12 //        第四步:把Operation加入到线程中
13         opQueue.addOperation(op)
14     }

 

使用BlockOperation创建operatoin,并直接运行。咱们看看会在哪条线程执行。

 1 //创建一个简单的BlockOperation
 2 private func CreatBasicBlockOperation() {
 3     //使用BlockOperation创建operation
 4     let operation = BlockOperation.init {
 5         //打印,看看在哪个线程中
 6         
 7         print(#function,#line,Thread.current)
 8     }
 9     
10     //直接运行operation,看看运行在哪个线程中
11     operation.start()
12 }

 

打印一下看看运行的结果:

这就是我们说,创建完Operation如果直接运行,就会在当前线程执行。也就是说,如果实在主线程创建并且start的,那就会在主线程执行;如果是在子线程创建并且start的,那就会在子线程执行。

 

3. Basic Demo

在这个例子里面,需求如下:
1,在子线程加载每个图片的数据
2,图片数据下载完毕之后,显示出来
3,开始请求数据的时候,让指示符开始转动
4,所有图片下载完毕后,指示符停止转动

 

3. Basic Demo

在这个例子里面,需求如下:
1,在子线程加载每个图片的数据
2,图片数据下载完毕之后,显示出来
3,开始请求数据的时候,让指示符开始转动
4,所有图片下载完毕后,指示符停止转动

 

3.2 Swift中的do catch

这个是Swift和OC不一样的地方。Swift中出现了可选值这么一个东西,这个不是这次的重点。想深入了解的童鞋可以参看这篇:?和 !的使用

Swift 里有四种方法来处理错误:

  1. 把错误从函数传递到调用函数的代码里
  2. 使用一个 do-catch 语句来处理错误
  3. 把错误当做一个可选值来处理
  4. 断言这个错误不会发生

 

因为Demo里面用到了do catch,那咱们就只说do catch.
在Swift的标准try中,是要配合do catch的。

下面是do-catch语句的一般格式,如果do分句内的代码抛出了一个错误,它就被catch分句捕获,并判断由哪个分句来处理此错误。

1 do {
2     try expression
3     statements
4 } catch pattern 1 {
5     statements
6 } catch pattern 2 where condition {
7     statements
8 }

3.3 优先级

在思维导图里面出现了两个优先级。一个是属于Operation 的,一个是属于OperationQueue的。那咱们分看看看这两个都是啥。

3.3.1 Operation中的优先级

Operation里面的这个叫做qualityOfService

1 public enum QualityOfService : Int {
2     case userInteractive
3     case userInitiated    
4     case utility    
5     case background    
6     case `default`
7 }
1 userInteractive:最高优先级,用于用户交互事件
2 userInitiated :次高优先级,用于用户需要马上执行的事件
3 utility:普通优先级,用于普通任务
4 background:最低优先级,用于不重要的任务
5 default:默认优先级,主线程和没有设置优先级的线程都默认为这个优先级

 

3.3.2 operationQueue 里面的优先级

operationQueue中表示优先级的属性是queuePriority,表示操作在队列中的优先级。

1 public enum QueuePriority : Int {
2     case veryLow
3     case low
4     case normal
5     case high
6     case veryHigh
7 }

这些优先级都是相对的,并不是是说必须要执行完最高的才执行次重要的。这里面并没有一个特别严格顺序。只是在分配资源上有倾向性。如果队列需要有严格的执行顺序,还是要添加依赖关系的,这个是我们下一篇文章要分享的内容。

4. 案例实现

Operation 基本应用及优先级小案例。
实现后效果如下:

 

 

 

这个Demo里面,用了两种方法创建Operation。

startBasicDemo,使用的是闭包创建Operation的方式。在startPriorityDemo里面使用的是自定义的构造方法创建的Operation,然后把任务数组加入到线程中。

代码:

 1 //    Operation 案例
 2     fileprivate func startBasicDemo()
 3     {
 4         let operationQueue = OperationQueue.init()
 5         operationQueue.maxConcurrentOperationCount = 3
 6         
 7         let activityIndicator = UIActivityIndicatorView()
 8         activityIndicator.startAnimating()
 9         
10         let a = UIImageView(frame: CGRect(x: 0, y: 64, width: 414, height: 100))
11         self.view.addSubview(a)
12         let b = UIImageView(frame: CGRect(x: 0, y: 164, width: 414, height: 100))
13         self.view.addSubview(b)
14         let c = UIImageView(frame: CGRect(x: 0, y: 264, width: 414, height: 100))
15         self.view.addSubview(c)
16         let d = UIImageView(frame: CGRect(x: 0, y: 364, width: 414, height: 100))
17         self.view.addSubview(d)
18         
19         
20         let imageViews = [a, b, c, d]
21         for imageView in imageViews {
22             if let url = URL(string: "https://placebeard.it/355/140")
23             {
24                 do {
25                     let image = UIImage(data:try Data(contentsOf: url))
26                     
27                     DispatchQueue.main.async
28                         {
29                             imageView.image = image
30                         }
31                 }catch
32                 {
33                     print(error)
34                 }
35             }
36         }
37 //        global queue
38         DispatchQueue.global().async
39             {
40                 [weak self] in
41 //            等待所有操作都完成了,回到主线程停止刷新器。
42 //            wait Until All Operations are finished, then stop animation of activity indicator
43                 operationQueue.waitUntilAllOperationsAreFinished()
44                 DispatchQueue.main.async
45                 {
46                     activityIndicator.stopAnimating()
47                  }
48     
49             }
50 }
View Code

 

设置了优先级的Demo:

 1 fileprivate func startPriorityDemo() {
 2     operationQueue.maxConcurrentOperationCount = 2
 3     activityIndicator.startAnimating()
 4     
 5     var operations = [Operation]()
 6     for (index, imageView) in (imageViews?.enumerated())! {
 7         if let url = URL(string: "https://placebeard.it/355/140") {
 8             //                使用构造方法创建operation
 9             let operation = convenienceOperation(setImageView: imageView, withURL: url)
10             
11             //根据索引设置优先级
12             switch index {
13             case 0:
14                 operation.queuePriority = .veryHigh
15             case 1:
16                 operation.queuePriority = .high
17             case 2:
18                 operation.queuePriority = .normal
19             case 3:
20                 operation.queuePriority = .low
21             default:
22                 operation.queuePriority = .veryLow
23             }
24             
25             operations.append(operation)
26         }
27     }
28     
29     //        把任务数组加入到线程中
30     DispatchQueue.global().async {
31         [weak self] in
32         self?.operationQueue.addOperations(operations, waitUntilFinished: true)
33         DispatchQueue.main.async {
34             self?.activityIndicator.stopAnimating()
35         }
36     }
37     
38 }
View Code

 

文章评论

我的丈夫是个程序员
我的丈夫是个程序员
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
 程序员的样子
程序员的样子
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
程序员应该关注的一些事儿
程序员应该关注的一些事儿
中美印日四国程序员比较
中美印日四国程序员比较
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
为什么程序员都是夜猫子
为什么程序员都是夜猫子
10个调试和排错的小建议
10个调试和排错的小建议
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
我是如何打败拖延症的
我是如何打败拖延症的
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序员必看的十大电影
程序员必看的十大电影
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员的鄙视链
程序员的鄙视链
代码女神横空出世
代码女神横空出世
鲜为人知的编程真相
鲜为人知的编程真相
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
程序员都该阅读的书
程序员都该阅读的书
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员和编码员之间的区别
程序员和编码员之间的区别
那些争议最大的编程观点
那些争议最大的编程观点
总结2014中国互联网十大段子
总结2014中国互联网十大段子
老程序员的下场
老程序员的下场
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
如何成为一名黑客
如何成为一名黑客
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
一个程序员的时间管理
一个程序员的时间管理
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有