最近这段时间一直在找工作 遇到了一些面试的问题 在解决这些问题的过程中看了很多大神的博客 于是想试着自己开始写一些东西,也可以和大家分享,如果有不足的地方 希望各位大神 指出 大家互相学习
首先:我们要知道什么是多线程 提到多线程又不得不提一下进程,线程,还有线程的串行
这里就不给大家一一说明了 相信对这篇帖子感兴趣的朋友都知道这些知识 如果不知道 可以自行百度,这里还是单独说一下多线程
1.什么是多线程:1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务
2.多线程的原理:同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象但是如果线程非常非常多,CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源每条线程被调度执行的频次会降低(线程的执行效率降低)
3.多线程的优缺点
多线程的优点:能适当提高程序的执行效率,能适当提高资源利用率(CPU、内存利用率)
多线程的缺点:开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能,线程越多,CPU在调度线程上的开销就越大,程序设计更加复杂:比如线程之间的通信、多线程的数据共享
4.开发iOS为什么要掌握多线程:
主线程:一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”,主线程的主要作用是显示\刷新UI界面\处理UI事件(比如点击事件、滚动事件、拖拽事件等),主线程的使用注意:别将比较耗时的操作放到主线程中。耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验,所以我们要把一些耗时操作放在子线程中执行;
iOS四套多线程的方案
(1)Pthreads
(2) NSThread
(3) NSOperation
(4) GCD
一:Pthreads
这个我从没有用过 相信也没有几家公司会用,百度百科的结果是:POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程,
简单的说就是支持多系统的一个API 但是没什么卵用 iOS可以用,不过是基于C语言的框架,这里就不多说了 因为我也没用过 这篇文章后边主要聊聊NSThread和NSOperation,GCD我想单独在写一篇终点介绍 ok 接下来我们接着往后聊
二:NSThread
相对比较轻量级 需要自己动手管理线程周期 线程同步 线程同步对数据加锁 有一定的系统开销
三种实现方法
//1.这种方法需要手动开启线程
NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(somethingToNsThread) object:nil];
[thread start];
//2.这种遍历构造的方法 不需要手动开启线程
[NSThread detachNewThreadSelector:@selector(threadDetachToDoSomething) toTarget:self withObject:nil];
//3.这种方法是NSObject自带的开启后台线程的方法
[self performSelectorInBackground:@selector(background) withObject:nil];
三:NSOperation
是基于OC实现的。NSOperation以面向对象的方式封装了需要执行的操作,然后可以将这个操作放到一个NSOperationQueue中去异步执行。不必关心线程管理、同步等问题。
NSOperation类是用来封装在单个任务相关的代码和数据的抽象类。因为它是抽象的,所以我们使用他的子类(NSInvocationOperation或NSBlockOperation)来执行实际任务
//三种实现方法
//1.利用target action的设计模式 让相应者去执行任务
NSInvocationOperation * operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationToDoSomething) object:nil];
//[operation start];
//2.这种方式利用OC里面经典的语法block(语法块)。但是和上者一样,如果单独使用NSOperation的子类对象必须手动的开启任务
NSBlockOperation * blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%d , %@",[NSThread isMainThread], [NSThread currentThread]);
}];
[blockOperation start];
//3.NSOperationQueue操作队列在开发中经常会使用到,比如我们做多任务下载的时候,使用自定义NSOperation子类和NSOperationQueue结合使用,每个NSOperation对象是一个任务,而NSOperationQueue却完美的担任了任务关系器的角色
//NSOperationQueue 里面只有串行的时候线程优先级才是可行的
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
//最大并发量 如果队列里的最大并发量为1 那么队列里面的任务将串行 也就是执行完一个任务在执行下一个 如果不为1 那就是并发执行
queue.maxConcurrentOperationCount = 1;
//添加block块
NSBlockOperation * block = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block, %d , %@",[NSThread isMainThread], [NSThread currentThread]);
}];
NSBlockOperation * block1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block1, %d , %@", [NSThread isMainThread], [NSThread currentThread]);
}];
NSBlockOperation * block2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block2 , %d , %@",[NSThread isMainThread], [NSThread currentThread]);
}];
NSBlockOperation * block3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block3 , %d , %@",[NSThread isMainThread], [NSThread currentThread]);
}];
//设置任务的优先级,只有队列为串行的时候优先级才能起到绝对的作用
[block setQueuePriority:(NSOperationQueuePriorityVeryHigh)];
[block1 setQueuePriority:(NSOperationQueuePriorityNormal)];
[block2 setQueuePriority:(NSOperationQueuePriorityLow)];
[block3 setQueuePriority:NSOperationQueuePriorityVeryHigh];
/**
这里多说一句 设置任务优先级是使用系统提供的几个枚举值 那么我已经在下边列出来了 简单的根据最后的英文 我们就可以判断出使用哪个优先级最高 哪个最低
NSOperationQueuePriorityVeryLow = -8L, 最低
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8 最高
*/
//设置依赖关系,只有执行完block之后才会去执行block1,这叫做任务block1依赖于block,
[block1 addDependency:block];
[queue addOperation:block3];
[queue addOperation:block1];
[queue addOperation:block2];
[queue addOperation:block];
这里多说一句我在上面将block 和 block3的优先级都设置的最高 那么执行顺序就是根据代码从上往下执行 先在队列中添加的block3所以会先log Block3,block1依赖于block 如果我只在队列中添加了block1而没有添加block的话block1也不会执行
今天先跟大家聊到这里 如果那里不足或不对的希望大家指正批评大家互相学习,那么之后我会在单独写一篇介绍GCD的