一
1.NSString用什么修饰符, 用strong会有什么影响?
-
一般用
copy, strong相当于浅拷贝, 如果是不可变的字符串没有什么影响. -
如果是可变的, 会因为对同一片内存地址操作, 导致别人可以修改到你指针指向的内存.
2.NSMutableString会用什么修饰?
- 用copy, 如果是可变类型, 赋值的时候会进行一次判断, 进行深拷贝.
- copy生成的是不可变的, mutableCopy生成的是可变的.
3.delegate用什么修饰?
assign或者weak
4.assign和weak有什么区别?
assign的所有权为__unsafe__retain, 指针所站空间不会被回收, 容易访问野指针weak有若引用计数表, 对象的isa上面有对应的weak标识. 对象回收的时候会清空计数表.- 如果确定指向的生命周期不会消失, 使用
assign也可以. - 总体来说就是
assign性能高不安全(不管指针),weak安全但是性能不高(清空指针).
5.block用属性生命一般用什么?
- 一般用
copy
6.用strong修饰block会有什么影响?
- 历史原因, 在
ARC下面使用strong和copy都一样, 都会进行copy到堆上. block捕获局部变量是copy, 局部静态变量是地址, 全局变量不捕获.
7.有用过@synthesize和@dynamic?
@synthesize主要是set, get方法以及成员变量的生成@dynamic防止生成set, get方法.
8.actomic和noactomic有什么区别?
- 原子性和非原子性
actomic可以保证读写安全, 但是不能保证线程安全.(假设读写在排队, 我进行release操作就炸掉了)noactomic不保证读写安全, 但是效率高.
9.actomic实现不了线程安全吗? 实际中用过吗?
actomic内部添加的是os_unfair_lock一把自旋锁.- 使用
atomic的场景 写入文件时,[data writeToFile:@"xxx.mp4" atomically:YES];
10.OC是一门运行时语言, 对于运行时的概念有什么印象?
- 对于
C语言来说在编译的时候就已经决定了调用什么函数, 编译完成之后直接顺序执行. - 对于
OC来说, 函数调用属于动态过程, 在真正的编译期并不能决定调用什么函数.只有运行时才可以检查调用的正确性.
11.KVC和KVO具体是实现什么功能?
- 解析plist文件或者JSON
- 观察者模式可以实现响应式编程
12.听说过线程安全吗? 什么样的情况下是线程不安全的?
- 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据.
13.线程不安全会有什么现象?
- 崩溃, 数据访问异常, 数据混乱, 野指针错误等
14.怎么解决这些问题?
- 加锁
- 同步队列同步任务或者同步队列异步任务+栅栏函数
- 信号量阻塞
15.在实际app的开发中有遇到过循环引用的现象吗?
- block的引用, 或者代理修饰符为strong时候的引用.
16.平常通过什么来判断这段代码是否循环引用?
Analyze静态分析: 主要分析以下四种问题:
- 逻辑错误: 访问空指针或者未初始化的变量
- 内存管理错误: 内存泄漏等
- 声明错误: 从未使用过的变量
- Api调用错误: 未包含使用的库或者框架
Instruments中的Leak动态分析
product->profile ->leaks可以快速定位到代码.
- 三方工具可直接使用, 简单.
MLeaksFinder是从UIViewController入手的,UIViewController在POP或dismiss之后该控制器及其上的view,view的subviews都会被释放掉,MleaksFinder就是在控制器POP或dismiss之后去查看该控制器和其上的view是否都被释放掉。
自定义监测工具
- 思路: 在VC
pop之后延时发送消息, 看看是否能响应, 可以响应就是没有释放. - 主要是
methodSwizzling进行方法交换 - 对
UIViewController添加分类, 交换viewWillAppear内部设置一个BOOL属性设置为NO. 对viewDidDisappear视图消失的时候进行取值判断. (动态添加属性) - 对
UINavigationController添加分类,HOOK``pop方法, 内部获取到VC然后动态给属性赋值. - 如果消息没有被发送, 那么延时消息将会打印.
- 只是思路, 小项目可以, 大项目要严谨使用方法交换.
17.有用过NSTimer吗? Timer在界面滑动的时候会暂停吗?
- 会, 和
runloop的运行模式有关.
18.开发app的时候遇到过崩溃的问题? 常见的几种崩溃, 解决的方法?
- 方法找不到,
runtime整个消息机制流程都可以, 看怎么处理了.有些是hook到forwardingTargetForSelector或者更后面的转发都可以. KVO未移除观察者- 集合类越界
- nil值替换
19.方法没有响应, doesNotRecognizeSelector?
- 还是消息流程结束调用.
20.判断一下方法有没有实现用什么?
- respondsToSelector
21.json解析的第三方库? 当你后端给你字典, 但是你定义的是数组什么怎么样?
- 会设置为
nil
22.定义了一个字段, 没有返回这个字段会有什么现象?
- 会设置为
nil, 建议还是看一下YYModel的内部实现, 待会儿会写一篇
23.写界面通过什么方式写?
- 纯代码, 布局
MAS
24.影响app流程程度的因素? 界面优化?
-
应用界面是一秒60帧可以保持流畅, 如果
CPU和GPU被大量占用, 无法在16.7毫秒内完成一帧的绘制, 导致渲染信号到来的时候取到上一帧的内容而导致卡顿. -
通常CPU渲染,和GPU非帧缓冲区内渲染统称为离屏渲染
-
CADisplayLinker可以进行软监测, 开启一跳子线程配合runloop监测主线程回调如果连续5次超过50ms, 则认定为卡顿, 存储堆栈信息上传. 对CPU处理的优化: -
在子线程中进行对象的创建,调整和销毁,节省一部分CPU的时间
-
在子线程中预排版(布局计算,文本计算),让主线程有更多的时间去响应用户的交互
-
对文本等异步绘制,图片编解码等内容进行 预渲染、预排版
对GPU处理的优化
- 尽量避免使用 CALayer 的 Border、corner、shadow、mask 等技术,这样能少触发离屏渲染
- 尽可能将多张图片合成为一张进行显示,减轻视图层级
25.什么情况下会导致离屏渲染?
- 多层图层进行合并的时候切圆角之类的操作, 苹果会先渲染好每一帧存入一个缓冲区叫做
离屏缓冲区, 经过层层叠加和处理之后, 在存储到帧缓存区去, 在屏幕上渲染 - 打开 Color Off-screen Rendered,同时我们可以借助Xcode或 Reveal 清楚的看到那些图层触发了离屏渲染。
26.为什么叫离屏?
- 因为在屏幕之外开辟了一个离屏缓冲区大还是屏幕像素的2.5倍. 一旦存入帧缓冲区的时间超过16.67ms , 容易造成卡顿,则会造成掉帧的情况.
总结
一线厂, 问的很基础, 没有特别深入, 一面就是大概了解一下基础, 对安全性的要求挺高的. 后续有的话继续更新