iOS 面试攻略,浅谈多线程开发1

最近这段时间一直在找工作 遇到了一些面试的问题 在解决这些问题的过程中看了很多大神的博客 于是想试着自己开始写一些东西,也可以和大家分享,如果有不足的地方 希望各位大神 指出 大家互相学习

首先:我们要知道什么是多线程 提到多线程又不得不提一下进程,线程,还有线程的串行

这里就不给大家一一说明了 相信对这篇帖子感兴趣的朋友都知道这些知识 如果不知道 可以自行百度,这里还是单独说一下多线程

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的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 首先明确线程和进程的关系和区别: 一个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程,使得多...
    kkj1996阅读 219评论 0 0
  • NSThread 第一种:通过NSThread的对象方法 NSThread *thread = [[NSThrea...
    攻城狮GG阅读 862评论 0 3
  • 在这篇文章中,我将为你整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项。当然也会给出几种多线程的案...
    张战威ican阅读 632评论 0 0
  • 有人说,这十二张美人图所绘的是雍正的宠妃年氏,没错,就是那位在热播电视剧中会抛白眼的贵妃娘娘。也有研究说,这是十二...
    张明lovelife阅读 214评论 0 0
  • 世界那么大,你要去寻找属于的爱。 世界那么大,只求能够在芸芸众生里,找到你。只求在我最美的日子里,遇见你,遇见爱情...
    若晨322阅读 363评论 0 2