iOSUI视图面试及原理总结
摘要:
1、UITableViewCell的重用机制描述一下?
2、UITableView相关的数据源同步问题,即如何在tableview解决多线程情况下,数据的处理?
3、是否遇到过卡顿和掉帧的问题,如何解决的,为什么出现卡顿和掉帧的问题?
4、绘制原理&异步绘制、什么是离屏渲染
5、图像显示的原理描述一下
6、iOS中的事件传递流程和视图响应流程
正问:
一、UITableViewCell的重用机制
在开发过程中,
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; - (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
有这两个方法调起UITableViewCell方的重用机制,在tableview新建的时候,会新建一个复用池viewreusepool,这个复用池在oc底层可能是一个队列,保存着当前cell.pool中的复用标识符就是reuseIdentifier,标识着不同种类的cell,所以当我们调用dequeueReusableCellWithIdentifier时,会通过当前reuseIdentifier查找到对应的cell,也就是展示的原型。
在创建tableview的时候,会创建一个空的viewreusepool,然后在tableview内部对pool进行管理,一般有两种用法,一种是取出一个空的cell的时候再去创建新的cell,另外一种是预先注册cell,之后再直接从复用池取出来用,不需要初始化.
对于第一种用法:第一次调用tableView:cellForRowAtIndexPath由于复用池是空的,会首先创建cell添加到复用池中,第二次调用,当前复用池中有一个cell,这时候因为talbeview上面还未填满,而且复用池的唯一的那个cell已经在使用了,所以取出来的cell仍然为nil,于是继续新建一个cell并返回,复用池再添加一个cell,当前复用池中cell的个数为2.假如当前tableview只能容纳5个cell.那么在滚动到第6个cell时,从tableview的复用池取出来的cell将会是第0行的那个cell.以此类推,当滚动到第7行时,会从复用池取出来第1行的那个cell. 另外,此时不再继续往复用池添加新的cell.
二、uitableview的数据源同步问题
如何解决在tableview中多线程情况下数据同步的问题?
有两种情况一:1、并行访问,数据拷贝,2、串行访问。
三、是否遇到过卡顿和掉帧的问题,如何解决的,为什么出现卡顿和掉帧的问题
首先卡顿是在规定的的16,7ms之内,下一帧sync信号到来之前,并没有cpu和gpu共同完成下一帧页面的合成,于是就会造成卡顿和掉帧。。
滑动优化方案:cpu:1、处理对象的创建、调整、销毁工作;2、欲排版(布局计算、文本计算);3、欲渲染(文本等异步绘制、图片解码等)gpu:1、纹理渲染;2、视图混合
四、绘制原理&异步绘制
绘制原理:
GPU屏幕渲染有以下两种方式:
1、当前屏幕渲染(On-Screen Rendering)
指的是在当前屏幕缓冲区内进行渲染
2、离屏渲染(Off-Screen Rendering)
指的是在当前屏幕缓冲区以外新开辟的一个缓冲区进行渲染操作
离屏渲染:
当我们处理图层的属性在被指定为未被预合成之前不能直接在屏幕上显示,就触发了离屏渲染,离屏渲染的概念起源于cpu层面,值得是cpu在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。
离屏渲染何时被触发?1、圆角(当和maskToBounds一起使用时,单独的圆角不触发);2、图层蒙版;3、阴影;4、光栅化;5、渐变
特殊的离屏渲染:CPU渲染 如果我们重写了drawRect方法,并且使用任何Core Graphics的技术进行了绘制操作,就涉及到了CPU渲染。整个渲染过程由CPU在App内 同步地完成,渲染得到的bitmap最后再交由GPU用于显示。
要尽量避免使用离屏渲染:1、上下文切换,gpu需要额外的开销;2、创建新的渲染缓冲区,内存消耗;
高级回答:触发离屏渲染会增加gpu的工作量,而增加了gpu的工作量很有可能导致cpu和gpu的工作总耗时超过了15.67ms,从而造成页面的卡顿和掉帧。