日常问题收录
1、OC中resolveInstanceMethod执行两次原因
当开发者实现了methodSignatureForSelector
并返回了方法签名后,会在forwardInvocation调用之前再次执行动态方法决议
2、block嵌套时强弱引用如何使用才安全 ?
保持一个weakSelf 对应一个 strongSelf
__weak typeof(self) weakSelf = self;
self.testBlock = ^{
__strong typeof(self) strongSelf = weakSelf;//第一层
NSLog(@"%@",strongSelf.hahah);
__weak typeof(self) weakSelf2 = strongSelf;
weakSelf2.testBlock = ^{
__strong typeof(self) strongSelf2 = weakSelf2;//第二层
NSLog(@"%@",strongSelf2.hahah);
};
};
3、字符串转int是如何实现的 ?
一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('\0')结束转换,并将结果返回
5、frame和bounds的区别是什么?
frame的参照物是父控件,bounds的参照物是控件本身 一般情况下两者的宽高是相等的
bounds影响到子view的位置和大小
6、GCD和Runloop的关系是什么 ?
GCD是一套c语言的多线程方案,其多数函数调用是不依赖runloop的只有需要回到主线程做事情的api才需要用到; runloop的底层实现有很多地方都在使用GCD的api, 比如runloop的定时器用的就是gcd的dispatch_source
7、有一台服务器 无限内存 无限算力 ipv4网络 端口80 问这台服务器能接收多少请求
8、是否可以把静态库打包成动态库/动态库打包成静态库
9、自己如何实现一个kvo
kvo的底层逻辑
10、CPU 和 GPU 的设计目的分别是什么?
CPU: 运算核心和控制核心需要有很强的运算通用性,兼容各种数据类型 同时需要处理大量的跳转、中断等指令,CPU设计的目标是低延时,更快的访问数据(因此有很多的告诉缓存);同时复杂的控制单元也能更快的处理逻辑分支 更适合做串行计算
GPU: 可进行绘图运算工作的专用微处理器,是连接计算机和显示终端的纽带
11、CPU 和 GPU 哪个的 Cache\ALU\Control unit 的比例更高?
Cache: 缓存
ALU: 算术逻辑单元 , 是能实现多组算术运算和逻辑运算的组合逻辑电路,简称ALU
ControlUnit: 控制单元
对比图.png
12、计算机图像渲染流水线的大致流程是什么?
- 应用处理阶段:得到图元信息
- 几何处理阶段:处理图元
- 图元转换为像素
- 像素处理阶段:处理像素 得到位图
13、Framebuffer 帧缓冲器的作用是什么?
用来储存显卡芯片处理过或即将提取的渲染数据,app通过CPU和GPU的合作不停的将渲染的内容放到Framebuffer中供视频控制器读取显示
14、Screen Tearing 屏幕撕裂是怎么造成的?
单缓存: 效率低只能呈现简单的图像,高清图费劲
双环存: 效率提升了, 但是信号不同步时会出现画面撕裂
双缓存+垂直同步信号: 不会出现画面撕裂 但内存不够用时会出现延时 导致掉帧
15、如何解决屏幕撕裂的问题?
双缓存+垂直同步信号(就是给帧缓冲器加锁),当电子枪完成一帧扫描后,需要进行下一次扫描的时候,就会发一个同步信号,当视频控制器收到垂直同步信号后才会将帧缓冲器中的内容替换成下一帧的,这样就避免了每次显示的内容都是同一帧的
16、掉帧是怎么产生的?
由于使用了Vsync,当收到Vsync的时候CPU和GPU如果还没渲染好位图,那么视频控制器就不会替换FrameBuffer中的内容, 电子束周期性去扫描展示的还是之前的FrameBuffer中的内容(掉帧了),当这个渲染的时间比较长的时候 就会导致多个屏幕刷新周期展示的是同一帧数据,当这个周期数超过人眼可以看出的范围就能明显感觉到卡顿
17、CoreAnimation 的职责是什么?
一个复合引擎主要职责是绘制可视化内容
18、UIView 和 CALayer 是什么关系?有什么区别?
创建一个UIView的时候会自动创建一个CALayer,UIView持有这个layer 并将layer的代理设置为UIView,所以UIView和CALayer具有相同的层级结构;
UIView主要是用来事件的处理
而CALayer主要是用来管理内部的可视内容,以及一些效果比如圆角
UIView继承自UIResponder,CALayer继承自NSObject
19、为什么会同时有 UIView 和 CALayer,能否合成一个?
为了职责分离拆分功能,方便代码的复用。通过Core Animation框架来负责可视内容的呈现,这样在iOS和OSX上都可以使用Core Animation进行渲染
20、渲染流水线中,CPU 会负责哪些任务?
- 处理触摸事件
- Commit Transaction
- layout: 视图的构建和布局
2.Display:绘制视图得到图元信息
3.Prepare: 图片的解码和转换
4.commit: 将图层打包并发送给Render Server,这里commit是按照视图层级递归调用的,所以图层过于复杂就会增加commit的开销,这也是为什么在做优化的时候要减少图层结构
21、离屏渲染为什么会有效率问题?
- 要开辟新的缓冲区
- 切换上下文环境
22、什么时候应该使用离屏渲染?
当一些效果需要保存图层的中间状态的时候,系统会触发离屏渲染,当界面中这种效果用的较少的时候可以考虑使用,但当这样的视图多了就会有性能瓶颈;
处于效率目的 可以将内容提前渲染保存在offscreen buffer中 达到复用的目的
23、shouldRasterize 光栅化是什么?
是否光栅化 当开启的时候会触发离屏渲染 系统会将layer渲染的bitmap保存起来,这样下次再需要渲染的时候就可以复用,从而提高效率;需要注意的是缓存的时效是100ms,如果这个时间内没有被使用就会被丢弃,同时离屏渲染的空间也是有限的是屏幕的2.5倍,超过该限制会被丢弃
24、有哪些常见的触发离屏渲染的情况?
- 视图的渲染是用的画家算法,由远及近去画图层,丢弃掉之前的;由于有一些效果需要对视图的所有图层都产生效果,那么就需要将这些中间效果保存,后续取出来进行效果加工
- 触发场景:圆角+裁切、阴影、遮罩、开启光栅化、设置组合透明度
25、cornerRadius 设置圆角会触发离屏渲染吗?
只设置cornerRadius不会触发离屏渲染,只有当需要裁切视图的时候才会需要保存中间状态
26、圆角触发的离屏渲染有哪些解决方案?
- 使用圆角背景图,对于复用多的图也可以代码绘制一个
- 使用贝塞尔去曲线画圆角
- 使用CG去绘制跟背景色一样的图片,根据视图的class决定怎么设置
27、重写 drawRect 方法会触发离屏渲染吗?
不会; drawRect是将视图的渲染交给cpu去处理了,并且需要额外开辟内存空间,它和标准意义上的离屏渲染并不一样,在instrument中开启离屏渲染调试时也会发现这并不会被判断为离屏渲染
28、NSTimer 循环引用解决 ? 用weak可以吗 ?
iOS 10以后可以使用block方式创建来避免,其原理是把timer传入block中了,用weak + strong可以的
29、Method Swizzling 需要注意事项是什么?说出三点?
iOS 开发:『Runtime』详解(二)Method Swizzling
- 应该只在 +load 中执行 Method Swizzling
- Method Swizzling 在 +load 中执行时,不要调用 [super load];
- Method Swizzling 应该总是在 dispatch_once 中执行
- 使用 Method Swizzling 后要记得调用原生方法的实现
- 避免命名冲突和参数 _cmd 被篡改
浏览器GET和POST的本质区别是什么 ?
- GET产生一个TCP数据包;POST产生两个TCP数据包,GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
GET与POST的本质区别 - GET请求会被浏览器主动cache,而POST不会,除非手动设置
30、给一个UIButton添加addTarget 、UIGestureRecognizer、以及重写 touchesBegan,最终会是谁被触发 ?增加难度(如果添加多个手势呢?)
会来到 -[UIButton touchesBegan:withEvent:] 之后执行最后添加的那个手势的action -- >tap1 -[ViewController tap1]
31、IPC了解吗 ?说说你在哪些场景使用过
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息 IPC的方式通常有管道(包括匿名管道和命名管道)、消息队列、信号量、共享内存等
1、URL scheme
这个是iOS APP通信最常用到的通信方式,APP1通过openURL的方法跳转到APP2,并且在URL中带上想要的参数,有点类似HTTP的get请求那样进行参数传递。这种方式是使用最多的最常见的,使用方法也很简单只需要源APP1在info.plist中配置LSApplicationQueriesSchemes,指定目标App2的scheme;然后再目标App2的info.plist 中配置好URLtypes,表示该App接受何种URL scheme的唤起。
2、Keychain
iOS 系统的keychain是一个安全的存储容器,它本质上就是一个sqlite数据库,它的位置存储在/private/var/Keychains/keychain-2.db,不过它索八坪村的所有数据都是经过加密的,可以用来为不同的APP保存敏感信息,比如用户名,密码等。iOS系统自己也用keychain来保存VPN凭证和WiFi密码。它是独立于每个APP的沙盒之外的,所以即使APP被删除之后,keychain里面的信息依然存在
3、UIPasteBoard
uipasteboard是剪切板功能,因为iOS 的原生空间UItextView,UItextfield,UIwebView ,我们在使用时如果长按,就回出现复制、剪切、选中、全选、粘贴等功能,这个就是利用系统剪切板功能来实现的。
4、UIDocumentInteractionController
uidocumentinteractioncontroller 主要是用来实现同设备上APP之间的贡献文档,以及文档预览、打印、发邮件和复制等功能。
5、Local socket
原理:一个APP1在本地的端口port1234 进行TCP的bind 和 listen,另外一个APP2在同一个端口port1234发起TCP的connect连接,这样就可以简历正常的TCP连接,进行TCP通信了,然后想传什么数据就可以传什么数据了
6、AirDrop
通过 Airdrop实现不同设备的APP之间文档和数据的分享
7、UIActivityViewController
iOS SDK 中封装好的类在APP之间发送数据、分享数据和操作数据
8、APP Groups
APP group用于同一个开发团队开发的APP之间,包括APP和extension之间共享同一份读写空间,进行数据共享。同一个团队开发的多个应用之间如果能直接数据共享,大大提高用户体验
32、XPC了解吗 ?说说你的认识
在iOS上有很多IPC(内部进程通讯)的方法,最简单最常见的IPC就是URL Schemes,也就是app之间互相调起并且传送简单字符的一种机制。比如我用[[UIApplication sharedApplication] openURL:url]这个api再配合”alipay://“, “wechat://”等url,就可以调起支付宝或者微信。
今天要讲的XPC比URLScheme要稍微复杂一点。XPC也是iOS IPC的一种,通过XPC,app可以与一些系统服务进行通讯,并且这些系统服务一般都是在沙盒外的,如果我们可以通过IPC控制这些服务的话,也就成功的做到沙盒逃逸了。App在沙盒内可以通过XPC访问的服务大概有三四十个,数量还是非常多的。
想要与这些XPC服务通讯我们需要创建一个XPC client,传输的内容要与XPC service接收的内容对应上,比如系统服务可能会开这样一个XPC service
33 RP了解过吗 ?
响应式编程 简称RP(Reactive Programming)响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播
34、NSOperation 与 GCD 的主要区别
观察(KVO)、取消、依赖、优先级、继承 、效率、并发数
-
GCD 的核心是 C 语言写的系统服务,执行和操作简单高效,因此 NSOperation 底层也通过 GCD 实现,换个说法就是 NSOperation 是对 GCD 更高层次的抽象,这是他们之间最本质的区别。因此如果希望自定义任务,建议使用 NSOperation;
-
依赖关系,NSOperation 可以设置两个 NSOperation 之间的依赖,第二个任务依赖于第一个任务完成执行,GCD 无法设置依赖关系,不过可以通过dispatch_barrier_async来实现这种效果;
-
KVO(键值对观察),NSOperation 和容易判断 Operation 当前的状态(是否执行,是否取消),对此 GCD 无法通过 KVO 进行判断;
-
优先级,NSOperation 可以设置自身的优先级,但是优先级高的不一定先执行,GCD 只能设置队列的优先级,无法在执行的 block 设置优先级;
-
继承,NSOperation 是一个抽象类,实际开发中常用的两个类是 NSInvocationOperation 和 NSBlockOperation ,同样我们可以自定义 NSOperation,GCD 执行任务可以自由组装,没有继承那么高的代码复用度;
-
效率,直接使用 GCD 效率确实会更高效,NSOperation 会多一点开销,但是通过 NSOperation 可以获得依赖,优先级,继承,键值对观察这些优势,相对于多的那么一点开销确实很划算,鱼和熊掌不可得兼,取舍在于开发者自己;
35、让你设计一种机制检测UIViewController的内存泄漏,你会怎么做?
当一个控制器触发了popViewController,popToViewController,popToRootViewController
在某一个时间阈值后其子控件还没有被制nil 这就有可能存在内存泄漏
36、通过[UIImage imageNamed:]生成的对象什么时候被释放?
使用imageNamed这个方法生成的UIImage对象,会在应用的bundle中寻找图片,如果找到则Cache到系统缓存中,作为内存的cache,而程序员是无法操作cache的,只能由系统自动处理,如果我们需要重复加载一张图片,那这无疑是一种很好的方式,因为系统能很快的从内存的cache找到这张图片,但是试想,如果加载很多很大的图片的时候,内存消耗过大的时候,就会会强制释放内存,即会遇到内存警告(memory warnings).
由于在iOS系统中释放图片的内存比较麻烦,所以冲易产生内存泄露。
像[[UIImageView alloc] init]还有一些其他的 init 方法,返回的都是 autorelease 对象。而 autorelease 不能保证什么时候释放,所以不一定在引用计数为 0 就立即释放,只能保证在 autoreleasepool 结尾的时候释放。
像 UIImage 还有 NSData 这种,大部分情况应该是延迟释放的,可以理解为到 autoreleasepool 结束的时候才释放