likes
comments
collection
share

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

作者站长头像
站长
· 阅读数 27

我的Github地址

小码哥《恋上数据结构与算法》笔记

极客时间《iOS开发高手课》笔记

iOS大厂面试高频算法题总结

iOS面试资料汇总

UITableView相关

一、重用机制

1、iOS如何实现cell的重用机制?

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • A1-A7使用相同的identifer,当tableView向上滑动,A1划出页面后,就被放入了重用池。
  • A7即将展示时,首先会在重用池中查看时候有相同identifercell可以被重用,如果有则直接取出使用,若无则创建一个新的cell

2、如何手动实现重用机制?

  • ViewReusePool类的声明 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
  • ViewReusePool类的实现 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
  • dequeueReusableView函数实现 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
  • addUsingView:函数实现 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
  • reset函数实现 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
  • ViewReusePool类的使用 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

二、数据源同步问题

  • 当数据源在主线程中有删除操作,同时在子线程上又有加载更多数据的操作时,就会出现数据源同步问题《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

1、数据源同步解决方案

a、并发访问、数据拷贝
  • 子线程返回主线程的数据中,仍然包含删除的这一条数据。《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
  • 主线程进行删除操作时,将操作记录下来。之后在子线程同步数据时,同步删除操作。 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
b、串行访问
  • 子线程的数据同步和主线程的删除操作全部放入一个串行队列中执行。
  • 删除动作可能会有延时。《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

事件传递&视图相应

一、UIView和CALayer

1、UIView和CALayer的关系和区别?

a、关系

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • UIView对象中的layer指向一个CALayer变量
  • UIView对象中的backgroundColor属性,是对CALayer同名属性的封装。
  • UIView展示部分是由CALayer中的contents来决定。contents对应的backing store其实是一个bitmap的位图。
b、区别
  • UIView为其提供内容,以及负责处理触摸等事件,参与响应链。
  • CALayer负责显示内容contents

2、为什么UIView负责触摸事件,CALayer负责显示?

  • 设计模式,单一职责原则。

二、事件传递与视图响应链

1、当点击View C2区域,系统是如何找到响应视图的呢?

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

a、事件传递的流程

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • 当用户点击屏幕,事件会被UIApplication接受,并传递给UIWindow
  • UIWindow调用hitTest函数,在hitTest内调用pointInside判断事件是否在该视图内。
  • 若为false,则返回该视图,事件传递流程结束。
  • 若为true,则可倒叙遍历该视图的子视图,并调用子视图hitTest函数。
  • 找到最终hitTesttrue子视图,并依次返回,事件传递流程结束。
b、hitTest系统内部实现

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • 在当前视图子视图调用hitTest函数前,需要将当前坐标转换为子视图中的坐标。 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

2、如何只让方形图片的圆形区域接受事件响应?《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • 重写视图的pointInside函数,使得点击区域在圆形范围内返回true,否则返回false《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

3、视图响应流程

a、事件的响应是通过响应链来传递的。

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • UIView通过继承UIResponder,拥有以下函数 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题
b、事件传递之后由谁来响应?

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • 如果响应视图无法处理响应事件,则响应事件会通过响应链传递给父视图尝试处理,直到传递给UIApplication
  • 如果传递给UIApplication依然没有处理响应事件,则事件将被忽略。

图像显示原理

一、图像显示流程

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • CPUGPU是通过事件总线链接在一起的。
  • CPU输出的位图,在适当时机由事件总线上传给GPU
  • GPU会对位图进行渲染,然后将结果放入帧缓冲区。
  • 视频控制器通过Vsync信号,在指定时间(16.7ms)之前,从帧缓冲区中提取屏幕显示内容,然后显示在显示器上。

二、UI视图显示过程

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • 当创建一个UIView对象,它的显示部分由CALayer来控制的。
  • CALayer有一个contents属性,就是最终绘制到屏幕上的位图
  • 在绘制contents内容时,系统会回调drawRect:函数,我们可以在函数中增加绘制内容。
  • 绘制好的位图会通过Core Animation框架,最终经由GPU当中的OpenGL渲染管线,渲染在屏幕上。

三、CPU工作过程

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

1、Layout

  • UI布局(frame设置)
  • 文本计算(size计算)

2、Display

  • 绘制(drawRect:

3、Prepare

  • 图片编解码

4、Commit

  • 提交位图

四、GPU渲染管线过程

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

卡顿&掉帧的原因

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • 按照每秒60FPS刷新率,每隔16.7ms就会有一次Vsync信号。
  • 16.7ms内,需要CPUGPU协同产生这一帧的画面,并在下一次Vsync信号来临时,显示这一帧的画面。
  • 如果CPUGPU的工作时长超过16.7ms,那么当Vsync信号来临时,无法提供这一帧的画面,就会出现掉帧现象。
  • 上一帧没有显示的画面,会在下一次Vsync信号来临时显示。

一、滑动优化方案

1、CPU

  • 对象创建、调整销毁可以放在子线程。
  • 预排版(布局计算、文本计算)操作,可以放在子线程操作。
  • 预渲染(文本等异步绘制图片编解码等)操作,降低CPU的耗时。

2、GPU

  • 避免离屏渲染,降低纹理渲染的耗时。
  • 如果视图层级复杂,GPU在视图合成时会做大量的计算。可以通过异步绘制等机制,减少视图层级,减轻GPU的压力。

绘制原理&异步绘制

一、UIView的绘制原理

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • 当调用setNeedsDispaly函数,实际是调用view.layersetNeedsDispaly函数。
  • 该函数会将layer标记,在runloop即将结束时,调用CALayer display函数,进入当前视图的真正绘制。
  • CALayer display函数中,会判断它的代理是否响应displayLayer:函数,如果YES,则可进行异步绘制,否则进入系统绘制流程

二、系统的绘制流程

《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

  • layer会创建一个backing store,在drawRect:函数中可以拿到这个上下文。
  • layer会判断是否有代理,如果有代理,在系统内部绘制完成后,会调用UIView drawRect:,允许在系统绘制基础上,进行增添修改。
  • 最终由CALayer上传backing storeGPU

三、异步绘制

  • 如果layer存在代理,则由代理执行display:函数生成位图,并设置该bitmap作为layer.contents属性。 《新浪微博剖析 iOS 高级面试》笔记(一):UI视图相关面试问题

离屏渲染

  • 在屏渲染(On-Screen Rendering)意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示屏幕缓冲区中进行。
  • 离屏渲染(Off-Screen Rendering)意为离屏渲染,指的是GPU的再当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。

一、什么场景会触发离屏渲染?

  • 圆角(需要和maskToBounds一起使用)
  • 图层蒙版
  • 阴影
  • 光栅化

二、为什么要避免离屏渲染?

  • 创建新的渲染缓冲区,会有内存上的开销。
  • 多通道渲染管线,最终需要合成,会涉及上下文切换,增加GPU的开销。
  • 总结:离屏渲染会增加GPU的处理时间,这样可能导致CPU + GPU的总处理时间超过16.7ms,从而出现掉帧卡顿的现象。

UI视图面试总结

  • 系统的UI事件传递机制是怎样的?
    • 考察hitTestpointInside内部实现。
  • 使UITableView滚动更流畅的方案或思路都有哪些?
    • CPU方面,在子线程进行对象的创建、调整、销毁、预排版、图片异步绘制
  • 什么是离屏渲染?
    • 在当前屏幕缓存区外,新开辟一个缓冲区进行渲染。
  • UIView 和 CALayer之间的关系是怎样的?
    • UIView负责事件传递事件响应
    • CALayer负责UI视图显示
    • 使用到设计模式六大设计原则中的单一职责原则。
转载自:https://juejin.cn/post/6899772676794122253
评论
请登录