本篇主要说一下多线程的东西,因为东西比较多,所以直接拿出一整个篇幅来说它了。

3、 多线程的底层实现?

1、先说一下什么是进程,什么是线程、什么是多线程。

进程是资源分配的单位,线程是调度运行的基本单位。多线程简而言之就是一个应用程序中,多个线程同步执行;多用于处理用户界面响应和网络访问的处理的同事进行,通常用子线程处理如网络访问等一些比较耗时的操作,同时不影响主线程在用户界面对用户操作的响应。

2、 Mach

Mach是第一个以多线程方式处理任务的系统,因此多线程的底层实现机制是基于Mach的线程,开发中很少用Mach级的线程,因为Mach级的线程没有提供多线程的基本特征,线程之间是独立的。

3、 开发中实现多线程的方案

1、C语言的pthread

2、OC的NSThread

3、 GCD

4、NSOperation和NSOperationQueue

4、线程间怎么通信?

这里借用这个问题,比较详细的回顾一下比较常用的三种多线程方案: NSThread、GCD、NSOperation和NSOperationQueue。

1、NSThread

先看它的线程间通讯:

 //去子线程执行耗时任务
// [self performSelectorInBackground:@selector(downloadSomething:) withObject:url]; // NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadSomething:) object:url];
// // 设置线程的优先级(0.0 - 1.0,1.0最高级)
// //thread.threadPriority = 1.0;
// [thread start]; [NSThread detachNewThreadSelector:@selector(downloadSomething:) toTarget:self withObject:url];

去子线程执行任务的三种方式。

 //回到主线程刷新界面
// [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO]; // [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO]; [self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];

耗时任务执行完毕之后回主线程刷新界面的三种方式。

还有一些其他的简单操作可以去demo看一下,这里就不多赘述了。

NSThread比其他两种多线程方案较轻量级,更直观地控制线程对象。但是需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销。

2、GCD

GCD的线程间通讯:

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{

         NSData *data = [NSData dataWithContentsOfURL:url];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
UIImage *image = [UIImage imageWithData:data];
UIImage *image1 = [UIImage imageWithData:data1];
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
self.imageView1.image = image1;
}); });

在子线程下载两张图片,回到主线程更新界面。

下面再看一下Dispatch Group:

Dispatch Group可以用来阻塞一个线程, 直到group关联的所有的任务完成执行。适用于有时候你必须等待任务完成的结果,然后才能继续后面的处理的情况。但是下面的这种场景其实个人认为是不需要这么做的,用上面的方式就好了。这里只为演示代码。

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );

     dispatch_async(queue, ^{
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
__block UIImage *image = nil; //注意block给image赋值,必须加__block前缀
__block UIImage *image1 = nil;
//往组中添加任务
dispatch_group_async(group, queue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
image = [UIImage imageWithData:data];
});
//往组中添加任务
dispatch_group_async(group, queue, ^{
NSData *data1 = [NSData dataWithContentsOfURL:url1];
image1 = [UIImage imageWithData:data1];
});
// 等待组中的任务执行完毕,回到主线程执行block回调
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
self.imageView.image = image;
self.imageView1.image = image1;
});
});

还有以下GCD的其他用法,写在demo里了,这里就不再赘述。下面看NSOperation和NSOperationQueue。

3、NSOperation和NSOperationQueue

     NSOperationQueue *queue = [[NSOperationQueue alloc] init];

     __block UIImage *image0 = nil;
__block UIImage *image1 = nil; // 创建3个操作
NSOperation *a = [NSBlockOperation blockOperationWithBlock:^{
NSData *data = [NSData dataWithContentsOfURL:url0];
image0 = [UIImage imageWithData:data];
NSLog(@"当前调用线程:%@", [NSThread currentThread]);
}];
NSOperation *b = [NSBlockOperation blockOperationWithBlock:^{
NSData *data = [NSData dataWithContentsOfURL:url1];
image1 = [UIImage imageWithData:data];
NSLog(@"当前调用线程:%@", [NSThread currentThread]);
}];
NSOperation *c = [NSBlockOperation blockOperationWithBlock:^{
[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image0 waitUntilDone:NO];
[self.imageView1 performSelectorOnMainThread:@selector(setImage:) withObject:image1 waitUntilDone:NO];
}]; // 添加依赖
[b addDependency:a];
// [c addDependency:a];
[c addDependency:b]; // 执行操作
[queue addOperation:a];
[queue addOperation:b];
[queue addOperation:c];

GCD和NSOperationQueue都属于不需要自己直接操作线程的,本人一般情况下都直接用GCD比较多,一来因为它高效,二来简洁方便。但是在像上面需要顺序执行,也就是需要用到依赖的时候,用NSOperationQueue比较方便。

同样的,其他关于NSOperation和NSOperationQueue的使用在这里不多赘述,希望再多了解一些的可以自行去demo看一下代码。

demo:https://github.com/alan12138/Interview-question/tree/master/4

5、GCD内部怎么实现的?

1、 iOS和OS X的核心是XNU内核,GCD是基于XNU内核实现的

2、 GCD的API全部在libdispatch库中

3、 GCD的底层实现主要有Dispatch Queue和Dispatch Source

Dispatch Queue :管理block(操作)

Dispatch Source :处理事件

6、 你用过NSOperationQueue么?如果用过或者了解的话,你为什么要使用NSOperationQueue,实现了什么?请描述它和GCD的区别和类似的地方(提示:可以从两者的实现机制和适用范围来描述)。

1、GCD是纯C语言的API,NSOperationQueue是基于GCD的OC版本封装

2、 GCD的执行速度比NSOperationQueue快

3、GCD只支持FIFO的队列,NSOperationQueue可以很方便地调整执行顺序、设置最大并发数量

4、 NSOperationQueue可以在轻松在Operation间设置依赖关系,而GCD需要写很多的代码才能实现

5、 NSOperationQueue支持KVO,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)

6、如何选择:任务之间不太互相依赖:GCD;任务之间有依赖\或者要监听任务的执行情况:NSOperationQueue

7.、既然提到GCD,那么问一下在使用GCD以及block时要注意些什么?它们两是一回事儿么?block在ARC中和传统的MRC中的行为和用法有没有什么区别,需要注意些什么?

Block的使用注意:

1、 block的内存管理(前面的题有讲到block)

2、防止强引用循环

避免强引用循环:

* 非ARC(MRC):__block(还有修改外部临时变量)

*  ARC:__weak\__unsafe_unretained

iOS的一些面试题分析总结(1)的更多相关文章

  1. iOS的一些面试题分析总结(0)

    虽然一些东西在实际工作中我们是很少用到的,但是面试确实会经常问到一些我们不常用的东西,所以说有时候看一看还是有必要的,一方面面试也是很重要的一件事,另一方面某些情况下也能帮我们查漏补缺. 一.NSNo ...

  2. 外企iOS开发的笔试题

    一组外企iOS开发的笔试题,您能回答出来吗?从群里收集来的. (miki西游@mikixiyou的文档,原文链接: http://mikixiyou.iteye.com/blog/1546376  转 ...

  3. QQ群里收集的外企iOS开发的笔试题

    一组外企iOS开发的笔试题,您能回答出来吗?从群里收集来的. 1 why can't NSArray contain NSInteger Instance? with which extra step ...

  4. iOS开发工程师笔试题

    iOS开发工程师笔试题 1.   Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? Object-c的类不可以多重继承:可以 ...

  5. iOS美丽约网络请求分析

    网络请求分析html, body {overflow-x: initial !important;}html { font-size: 14px; } body { margin: 0px; padd ...

  6. 使用java理解程序逻辑 试题分析

      1.编译Java Applet源程序文件产生的字节码文件的扩展名为() A:.java B..class C:Html D:Exe 正确答案:B 试题分析: 本题考查的是Java程序的开发过程.J ...

  7. iOS常用框架源码分析

    SDWebImage NSCache 类似可变字典,线程安全,使用可变字典自定义实现缓存时需要考虑加锁和释放锁 在内存不足时NSCache会自动释放存储的对象,不需要手动干预 NSCache的key不 ...

  8. iOS面试必看经典试题分析

    > **不用临时变量怎么实现两个数据的交换?** 方式一:加减法的运算方式求解new_b = a - b + b = a;new_a = a + b - a = b;一个简单的运算方式,最重要的 ...

  9. iOS之2016面试题二

    前言 招聘高峰期来了,大家都非常积极地准备着跳槽,那么去一家公司面试就会有一堆新鲜的问题,可能不会,也可能会,但是了解不够深.本篇文章为群里的小伙伴们去要出发公司的笔试题,由笔者整理并提供笔者个人参考 ...

随机推荐

  1. 学习笔记:因为java匿名类学习到接口的一些小用法

    在看CometD的示例代码时发现了许多有意思的代码,但说实话看别人的代码确实是件很累的事情,所以就看到这个知识点做一下记录吧.   先看一段代码: 代码1   这段代码中有一个new的操作,而且是在方 ...

  2. ReactJs笔记

    中文教程:http://reactjs.cn/ 实例: http://www.ruanyifeng.com/blog/2015/03/react.html

  3. 发布两款JQ小插件(图片查看器 + 分类选择器),开源

    图片查看器,github地址:https://github.com/VaJoy/imgViewer 效果如下: 这款当初大概写了2小时,有点匆忙地赶出来的,使用的接口很简单: $.bindViewer ...

  4. LOMA280保险原理读书笔记

    LOMA是国际金融保险管理学院(Life Office Management Association)的英文简称.国际金融保险管理学院是一个保险和金融服务机构的国际组织,它的创建目的是为了促进信息交流 ...

  5. 关于大型网站技术演进的思考(二十)--网站静态化处理—web前端优化—中(12)

    Web前端很多优化原则都是从如何提升网络通讯效率的角度提出的,但是这些原则使用的时候还是有很多陷阱在里面,如果我们不能深入理解这些优化原则背后所隐藏的技术原理,很有可能掉进这些陷阱里,最终没有达到最佳 ...

  6. ASP.NET MVC 从零开始 - 自动化部署(其二)

    这篇文章是从我的 github 博客 http://lxconan.github.io 导入的. 这是这个系列的第五篇了,前四篇请参见: ASP.NET MVC 从零开始 – Create and R ...

  7. 非正规方法处理AngulurJS模块管理问题

    1.起因 自己一直做winform,有幸从某个大神手里接了一个node.js,express,angulurJS等集众多开源框架的一个项目,赶鸭子上架,于是一边学习,一边用自己以往的思中去整理,重构代 ...

  8. Ajax_04之jQuery中封装的Ajax函数

    1.PHP中json_encode编码规则: PHP索引数组编码为JSON:[...] PHP关联数组编码为JSON:{...}2.jQuery中AJAX封装函数之load: ①使用:$('选择器') ...

  9. 【深入浅出Linux网络编程】 “实践 -- TCP & UDP”

    通过上一篇博客的学习,你应该对基于epoll的事件触发机制有所掌握,并且通过阅读sio.c/sio.h应该也学会了如何封装epoll以及如何通过设计令epoll更加实用(用户回调,用户参数). 简单回 ...

  10. 【非愚人】重要通知:04-01 贴吧继PHP资源之后又。。。

    贴吧继PHP资源之后又取消了JAVA,IOS等资源的贴,现在专注于Net,C++,Linux,平面设计.主要是为了让广大Net程序员具备全栈全平台牛人的潜力,故而取消那些干扰因素.Net的潜力和活力大 ...