1.异常和捕获
1.try-catch
@try{
//raise exception
}
@catch (NSException *exception) {
// cannot raise exception
}
@finally {
// execute
}
// execute
2.捕获
NSSetUncaughtExceptionHandler
3、线上崩溃分析
在上面的捕获函数中,捕捉堆栈。
[NSThread callStackSymbols]
4、线上卡顿统计 CADisplayLink每帧回调,用时间间隔算帧率; 计算每次runloop的耗时。
2.KVO与Notification的异同
KVO和Notification本质都是观察者模式。
KVO是被观察者直接发消息(-willChange和-didChange),耦合性较强,适合某些绑定,比如说界面上的进度条显示;
Notification是被观察者发消息给NotificationCenter,再由NotificationCenter转发出去,耦合性较低,适合登录、等级变化、监听全局的某个属性变化;
3.Objective-C消息机制的原理
先介绍Objective-C的类结构:
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
typedef struct objc_class *Class;
每一个OC对象本质上都是一个结构体,包括成员变量列表和成员方法列表,对象通过isa指针指向类;
类本质上也是一个对象,是元类(meteClass)的实例,元类包括类方法的列表,类通过类的isa指针指向元类;
所有的元类继承根元类,根元类isa指针指向本身;
objc_msgSend方法:objc_msgSend含两个必要参数:receiver、方法名(selector)
[receiver message];将被转换为:objc_msgSend(receiver, selector);
带参数的情况是:objc_msgSend(receiver, selector, arg1, arg2, …);
当向一个对象发送消息时,objc_msgSend方法根据对象的isa指针找到对象的原来类,然后在类的方法列表中查找selector;
如果查找不到,通过Class super_class指针找到父类,并在父类的方法列表查找,直到NSObject类;
查找到selector,objc_msgSend方法根据方法列表的内存地址调用该实现;
每个类都有一个独立的缓存struct objc_cache *cache,缓存方法调用的结果。
4.对象回收时Weak指针自动被置为nil的实现原理
Runtime维护着一个Weak表,用于存储指向某个对象的所有Weak指针; Weak表是Hash表,Key是所指对象的地址,Value是Weak指针地址的数组; 在对象被回收的时候,经过层层调用,会最终触发下面的方法将所有Weak指针的值设为nil。
runtime源码,objc-weak.m 的 arr_clear_deallocating 函数。
Weak指针如何注册到Weak表中、如何维护hash表可以参考objc-weak.m中的其它源码。
从实现中可以看出,Weak指针的使用涉及到Hash表的增删改查,有一定的性能开销。 Weak指针的实际应用:
iOS 8 特有iOS相关的漏洞
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
iOS 8 的UIScrollView的delegate属性
5. 动画性能优化
动画的视图结构
视图树/图层树:UIView,每个view对应一个calayer,管理触摸、手势等交互事件;
模型树/逻辑树(目标帧) :CALayer - modelLayer(),不涉及响应链(通过视图层级关系传递触摸事件的机制)
呈现树/动画树(当前帧) :presentationLayer(), 动画过程中的当前值
渲染树/显示树(下一帧) :图层和动画打包提交到渲染服务后反序列化所得树,被用于生成gl三角形
动画耗时在于: 图片加载、alpha透明、动画代码混乱、离屏渲染、帧动画过多、布局计算、遮罩、图片过大;
某些问题不可避免,比如说图片加载、帧动画等,以下是自己总结的一些经验:
-
CADisplayLink控制帧动画的帧率,避免动画的绘制速率超过帧率;
-
避免使用alpha透明的图片;
-
使用GCD和CAAnimation来管理动画的流程;
使用NSOperationQueue或许也是解决方案。 -
减少遮罩以避免离屏渲染,避免光栅化视图的频繁更新;
-
使用代码布局,避免autolayout;
6.TCP/IP
3次握手-建立连接 1、A发送sync报文;seq=x Sync=1 2、B回复ack报文;seq=y Sync=1 ack=x+1 3、A回复ack报文;seq=x+1 Sync=1 ack=y+1
4次握手-断开连接 1、A端发送FIN,停止发送报文;A进入FIN-WAIT 2、B端发送ACK,表示收到,继续发送报文; A收到报文进入FIN2-WAIT 3、B端发送FIN,停止发送报文;B进入CLOSE_WAIT 4、A端收到FIN,发送ACK报文,A进入TIME_WAIT状态
TIME_WAIT经过两个最大报文段生存时间后,进入CLOSE状态。(如果A在time_wait过程中,收到FIN报文,表示发送的ACK丢包了,重新发)
7.APP的生命周期
应用程序的状态
Not running未运行:程序没启动;
Inactive未激活:程序在前台运行,未接收到事件;
Active激活:程序在前台运行,接受到事件;
Backgroud后台:程序在后台运行,在后台停留一段时间后进入挂起状态(Suspended),如果有音乐、下载等特殊任务的程序可以长期处于Backgroud状态;
Suspended挂起:程序在后台且不运行,当收到系统内存不足的warning时被清除出内存;
问题1:UIAlertView弹出的时候,APP处于哪一个状态? 低电量提出弹出的时候,APP又处于哪一个状态?
Inactive和Background。
8.HTTP协议
http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式 http请求由三部分组成,分别是:请求行、消息报头、请求正文。 常见状态码: 200 成功 400 请求的语法错误 403 Forbidden 404 not found 服务器找不到请求的资源 408 Request Time out 500 服务器内部错误
请求头 GET 请求方法、地址、协议版本 GET /foo.php?first_name=John&last_name=Doe&action=Submit HTTP/1.1
请求体(POST请求有) form-data