所有的app都会有一个进程,会有多个线程。可以简单理解为主线程就是那个唯一的进程。
在iOS中主线程主要是用来进行UI操作的。
在整个操作系统中,主线程的优先级是最高的。
【线程】
同步:所有的任务在一个线程中执行,当前一个任务未能完成时,后一个任务被阻塞。
异步:不同的任务在不同的线程中执行,当开辟的子线程或称工作线程发生阻塞,主线程或其他线程不会受到影响。
串行:当一个线程执行多个任务,会采用执行完一个,再执行一个的方式,这种执行任务的方式称为串行。
并发:多个线程分担多个任务,不同的任务同时执行,称为并发。
【注】异步和并发的概念不完全相同。异步强调的是解决主线程(在IOS中亦称UI主线程)的阻塞。并发,一般指子线程或称工作线程之间的关系。多个工作线程分担任务称为并发执行任务。
一、什么是线程
1.线程(Thread)是进程内部的并行执行代码片段的机制
2.线程能防止UI的假死
3.线程是处理异步任务的主要手段
二、线程的分类
1.UI主线程:UI Main Thread
2.工作线程:Worker Thread(次级线程)
主线程是系统自动创建,一般的代码都执行在UI主线程中。但如果工作内容会导致主线程阻塞,造成程序假死,则需要我们手动创建工作线程。
三、线程的实现
iOS中实现线程的可行方式有:
NSThread Objective-C的线程类
【允许开发者手动管理线程的生命周期,可以手动开启或者销毁线程。】
NSOperationQueue 线程池/线程队列
【每一个Operation都是一个线程,不需要开发者管理线程的生命周期,并且可以设置最大并发数,管理方便,使用最多。网络请求相关的三方库大部分都是使用这个。】
GCD 使用Block语法的线程池/线程队列
【苹果封装的C语言级别的线程池/线程队列,可以灵活的使用CPU的多核高效的处理线程问题。是效率最高的多线程。】
【NSThread】
1.创建线程
这种方法开启的线程会自动启动
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
使用常规的方法初始化
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
这种初始化需要开发者自己手动开启线程的执行
启动线程
- (void)start;
//取消并不等于退出线程
- (BOOL)isCancelled;
- (void)cancel;
退出线程
+ (void)exit;
当前线程休眠
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
//判断当前是否处于多线程工作状态
+ (BOOL)isMultiThreaded;
//给线程设置名字
- (void)setName:(NSString *)n;
- (NSString *)name;
//判断当前线程是否是主线程
- (BOOL)isMainThread;
+ (BOOL)isMainThread;
//判断当前线程是否已经执行
- (BOOL)isExecuting;
//判断当前线程是否已经完成,如果已经完成,应当结束线程
- (BOOL)isFinished;
2.为什么要线程-防止界面假死
写一个循环,再循环中读秒休眠。
在线程中执行上面的描述。
3.如何监听线程结束
在通知中心注册名字为:NSThreadWillExitNotification的通知
4.多个线程之间同步
4.1创建一个线程0,并且保持永久执行。
4.2创建一个线程1,当时机合适,通知线程0结束执行。
4.3线程0收到通知,结束执行
5.线程锁2个线程加1减1
相关的类 NSLock
6.NSThread线程触发进度条
和刷新UI相关的内容和操作,全部要放在主线程中来执行。这也是为什么系统会自动创建主线程,并且保持最高优先级,因为UI界面的卡顿或者假死会造成不好的用户体验。
【提示】网络请求由于中国移动互联网的情况,速度并不快,所以多采用多线程的方式来处理网络请求的操作。专门开辟一个线程来抓取资源,当数据资源抓取完毕后,交给主线程来刷新UI。
7.NSOperation
创建一个block任务
NSBlockOperation
创建一个调用任务(通知类似的)
NSInvocationOperation
任务队列,任务初始化后,加入队列,就会执行
当任务方法调用结束后就会自动销毁任务
NSOperationQueue
添加任务
- (void)addOperation:(NSOperation *)op;