2022年iOS最新面试(底层基础)问题答案
Posted super_man_风清扬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022年iOS最新面试(底层基础)问题答案相关的知识,希望对你有一定的参考价值。
文章目录
Runloop
答:本质是一个OC对象,内部也有isa指针。
答:线程和 RunLoop 之间是Key-value的对应关系,是保存在一个全局的 Dictionary 里,线程是key,RunLoop是value,而且是懒加载的。
3、Runloop的底层数据结构是什么样的?有几种 运行模式(mode)?每个运行模式下面的 CFRunloopMode 是哪些?他们分别是什么职责?
答:Runloop的底层数据结构(NSRunLoop是CFRunLoop的封装):
CFRunLoop,RunLoop对象
Mode,运行模式
Source,输入源/事件源
Timer,定时源
Observer,观察者
系统默认注册了5个Mode常用的有3个 常见的几种Mode:
Default : App的默认Mode,通常主线程是在这个Mode下运行
UITracking: 界面跟踪Mode,用于ScrollView`追踪触摸滑动,保证界面滑动时不受其他Mode影响。
Common :并不是一个真的模式,它只是一个标记,如:被标记的 Timer可以在Default模式和UITracking下运行。
基本用不到的Mode:
UIInitialization :私有的mode,App启动的时候的状态,加载出第一个页面后,就转成了Default
GSEventReceive系统的内部 Mode,通常用不到
答:Entry->BeforeTimers->BeforeSources->BeforeWaiting(休眠)->AfterWaiting(唤醒)->Exit->AllActivities
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity)
kCFRunLoopEntry = (1UL << 0), // 即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理Timer
kCFRunLoopBeforeSources = (1UL << 2), // 即将处理Source
kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒
kCFRunLoopExit = (1UL << 7), // 即将退出Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU // 所有状态
;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
答:滑动scrollview时候的mode切换,cell的图片下载 将多个耗时操作分开执行,在每次 RunLoop
唤醒时去做一个耗时任务。
答:CPU的两种工作状态:内核态和用户态(或者称管态和目态)
内核态:系统中既有操作系统的程序,也由普通用户的程序。为了安全和稳定性操作系统的程序不能随便访问,这就是内核态,内核态可以使用所有的硬件资源。
用户态:不能直接使用系统资源,也不能改变CPU的工作状态,并且只能访问这个用户程序自己的存储空间。
线程、队列、锁
答:线程是系统调度的最小任务单位,队列是存放管理任务单位的数据结构。
答:不,同步执行方式是不创建新线程的,就在当前线程嗨。
线程按执行方式分为同步、异步,按队列管理分为串行并行,这样有四种组合,加上常说的主线程主队列,那么结合执行方式就有六种组合。
同步串行,不创建线程,所以还是在当前线程一个一个做
同步并行,不创建线程,所以就算是并行,也还是在当前线程一个一个做
异步串行,开辟多一条线程,任务在新开辟的一条线程里面一个一个做
异步并行,开辟多条线程,任务在新开辟的线程里面一起做
同步主队,阻塞
异步主队,同异步串行,因为主队就是串行,但是不开辟新线程,因为主线程是全局的单例的
答:不能,队列也是对象,要占用内存,受限于硬件资源,不能无限制创建。
4、PerformSelector & NSInvocation优劣对比
答:相同点: 有相同的父类NSObject 区别: 在参数个数<= 2的时候performSelector:的使用要简单一些,但是在参数个数 > 2的时候NSInvocation就简单一些。
答:dispatch_block_cancel可以取消尚未执行的任务。已经在运行的,用代码中断
答:想让线程不死掉的话,需要为线程添加一个RunLoop
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
// 往RunLoop里面添加Source\\Timer\\Observer,Port相关的是Source1事件
// 添加了一个Source1,但是这个Source1也没啥事,所以线程在这里就休眠了,不会往下走,----end----一直不会打印
[runLoop addPort:[NSMachPort port] forMode:NSRunLoopCommonModes];
[runLoop run];
- 1
- 2
- 3
- 4
- 5
GCD
答:
NSThread是早期的多线程解决方案,实际上是把C语言的PThread线程管理代码封装成OC代码。
GCD是取代NSThread的多线程技术,C语法+block。功能强大。 充分利用多核,效率最高
NSOperationQueue是把GCD封装为OC语法,额外比GCD增加了几项新功能。 最大线程并发数 取消队列中的任务 暂停队列中的任务
可以调整队列中的任务执行顺序,通过优先级 线程依赖 NSOperationQueue支持KVO。 这就意味着你可以观察任务的状态属性。
但是NSOperationQueue的执行效率没有GCD高,所以一半情况下,我们使用GCD来完成多线程操作。
答:
GCD是取代NSThread的多线程技术,C语法+block。功能强大。
充分利用多核,效率最高 NSOperationQueue是把GCD封装为OC语法,额外比GCD增加了几项新功能。
最大线程并发数
取消队列中的任务
暂停队列中的任务
可以调整队列中的任务执行顺序,通过优先级
线程依赖
NSOperationQueue支持KVO。 这就意味着你可以观察任务的状态属性。
但是NSOperationQueue的执行效率没有GCD高,所以一半情况下,我们使用GCD来完成多线程操作。
docx正在上传…重新上传取消0星超过10%的资源107KB
答:barrier栅栏功能,栅栏前不管多少个异步都要执行完毕,才会执行栅栏后面的操作。
可以尝试用信号量来实现,例如A、B、C、barrier、D并发,但是希望ABC完成后D才开始。
设定线程信号量最大值为3,ABC先执行,等ABC都执行完,D才开始
答:第一串行队列,第二并行队列,第三分组,第四信号量。
串行,一个一个执行,有同步操作的效果
并行,先开一个异步线程,把多个同步线程放在该异步中执行并行
分组,dispatch_group_notify()提供了一个知道group什么时候结束的点
信号量,信号量和锁的作用差不多,可以用来实现同步方式
执行一个 NSThread 任务, 如何在执行过程中让他终止?
答://监测当前线程是否被取消过,如果被取消了,则该线程退出。在线程里面检测取消的标记,然后执行退出 if ([[NSThread
currentThread] isCancelled]) [NSThread exit];
ios NSOperation 是如何终止/取消任务的?
答:正在执行的任务,NSOperation也是不能取消的,可以考虑用一个条件来做,满足条件则执行此任务,不满足则不执行
多线程,异步执行(async)一个performSelector 会执行么?如果加上 afterDelay呢?
答:performSelector会执行,afterDelay不会执行;原因performSelector只是单纯的直接调用某函数,afterDelay是在该子线程执行一个NSTimer,注意一点:子线程中的runloop默认是没有启动的状态,要想afterDelay生效,要runloop在线程有事务的状态下跑起来,所以需要执行[[NSRunLoop
currentRunLoop] run]。
答:莫名其妙的题目,要阐述怎么用GCD缔造出NSOperationQueue吗
答:线程优化,告诉系统是什么类型的任务。
user_interactive:用户交互(希望尽快完成,用户对结果很期望,不要放太耗时操作)
user_initiated:用户期望(不要放太耗时操作)
default:默认(不是给程序员使用的,用来重置对列使用的)
utility:实用工具(耗时操作,可以使用这个选项)
background:后台
unspecified:未指定
iOS 7.0 之前 优先级
priority_high:高优先级
priority_default:默认优先级
priority_low:低优先级
priority_backgroud:后台优先级
以上是关于2022年iOS最新面试(底层基础)问题答案的主要内容,如果未能解决你的问题,请参考以下文章