故事背景:忙碌了一周的程序员陈先生终于等来了周六早上,打算去喜茶看看,结果看到喜茶店只有一个窗口,后面排着一大条队伍(其实都是喜茶的托,你懂的),陈先生心里大骂:“MMP,原来是单线程,就不能拿雇托的钱多开几条线程吗?”
问题来了:什么是线程? 可以吃吗?
工欲善其事,必先利其器。所以弄清楚这些基本概念是学好多线程的基础。
进程: 指一个正在运行的应用程序。在故事中就好比喜茶店。 线程: 一个进程想要执行任务,就必须要有线程。一个进程中至少包含一条线程,该线程被称为主线程。例如喜茶的售货窗口就是一条线程。 多线程: 除主线程外开启一条或多条线程,同时(并行)执行不同的任务。这也是陈先生所希望的,多个窗口能提高销售效率。 多线程原理:CPU快速在各线程之间调度。 同步: 任务执行完成后再执行另一个,只在当前线程执行。例如背景故事中只允许一个窗口排队购买喜茶 异步: 任务每次允许完成多个。例如背景故事中陈先生希望的,多个窗口能同时排队购买。 队列: 队列是用来管理线程的,复制创建和回收线程,是先进先出(FIFO)结构的。分为串行队列和并发队列。 串行队列: 任务按照顺序被调度,前一个任务不执行完毕,队列不会调度。 并发队列: 只要有空闲的线程,队列就会调度当前任务,交给线程去执行,不需要考虑前面是都有任务在执行,只要有线程可以利用,队列就会调度任务。
同步、异步、串行、并发 组合结果:
串行队列+同步任务:不会开启新的线程,任务逐步完成。串行队列+异步任务:开启新的线程,任务逐步完成。并发队列+同步任务:不会开启新的线程,任务逐步完成。并发队列+异步任务:开启新的线程,任务同步完成。iOS中有很多的多线程技术可供选择,到底选择哪一种后面会说的,这里只简单介绍几种多线程技术。
这里指介绍三种多线程技术:NSThread, NSOperation, GCD.
NSTread需要手动开启线程
[thread1 start]; 线程暂停/休眠 [NSThread sleepForTimeInterval:2.0/*休眠的时间*/]; [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]; 线程取消 [thread1 cancel]; 线程停止 [thread1 exit]; 获取当前线程 [NSThread currentThread]; 获取主线程 [NSThread mainThread]; 设置优先级iOS8以前使用
[NSThread setThreadPriority:1.0];iOS8以后推荐使用
// NSQualityOfServiceUserInteractive:最高优先级,用于用户交互事件 // NSQualityOfServiceUserInitiated:次高优先级,用于用户需要马上执行的事件 // NSQualityOfServiceDefault:默认优先级,主线程和没有设置优先级的线程都默认为这个优先级 // NSQualityOfServiceUtility:普通优先级,用于普通任务 // NSQualityOfServiceBackground:最低优先级,用于不重要的任务 [newThread setQualityOfService:NSQualityOfServiceUserInitiated];备注:一般用于更新UI
指定某条线程上操作 [self performSelector:@selector(method) onThread:thread1 withObject:nil waitUntilDone:YES]; //这里指定为thread1线程 [self performSelectorInBackground:@selector(method) withObject:nil];//这里指定为后台线程优点: 简单,易操作,轻量级的iOS多线程工具。
缺点: 需要手动管理所有的线程活动,如生命周期、线程同步、睡眠等。
NSOperation需要和NSOperationQueue配合才能实现多线程编程。具体步骤如下:
先将需要执行的操作封装到一个NSOperation的子类对象中;(NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类)然后将NSOperation对象添加到NSOperationQueue中;系统会自动将NSOperationQueue中的NSOperation取出来;将取出的NSOperation封装的操作放到一条新线程中执行。NSOperation是一个抽象类,不具有封装任务的能力,必须使用它的子类来封装任务。它的子类如下:
NSInvocationOperation:具体项目中较少用;NSBlockOperation:相对较常使用该子类;自定义子类继承NSOperation:很少使用。详细运用如下:
NSInvocationOperation(未完待续)