美文网首页
# UI视图相关

# UI视图相关

作者: Sendom | 来源:发表于2018-06-04 13:09 被阅读0次

    UI视图相关

    1. UITableView
    2. 事件传递&视图响应
    3. 图像显示原理
    4. 卡顿&掉帧
    5. 绘制原理&异步绘制
    6. 离屏渲染

    1. UITableView

    1. 重用机制
    2. 数据源同步(多线程)

    重用机制

    1. cell = [UITableView dequeueReusableCellWithIdentifier:@"identifier"];
    2. 不在屏幕上的cell 放到重用池中,即将在屏幕上显示的cell用相同的重用标识符从重用池中取得缓存的cell

    数据源同步(UI刷新错乱)

    1. 并发访问,数据拷贝
    2. 串行访问

    2. 事件传递&视图响应

    1. UIView和CALayer
    2. 事件传递与视图响应链

    1. UIView和CALayer

    1. UIView显示的部分是CALayer的contents(backing store),UIView的backgroundColor是CALayer的同名属性的封装
    2. 区别
      1. UIView 为CALayer提供显示的内容,以及负责触摸灯事件,参与响应链(设计原则,单一职责原则)
      2. CALayer只负责内容contents的显示

    2. 事件传递与视图响应链

    1. 涉及的两个方法hitTest:withEvent:(方法一)与pointInside:withEvent:(方法二)

    2. 流程:

      1. 用户点击了屏幕,硬件接收到点击事件后,由UIKit(硬件驱动)处理包装事件,发送给桌面,如果桌面当前没有程序在运行,就转换成自己的事件,如点击APP图标启动APP,滑动APP列表,或者打开通知中心等。如果有APP在前台运行,就把事件传给APP,APP会利用RunLoop处理事件。
      2. App会把事件分发给当前的UIWindow对象,UIWindow对象会调用方法一返回对应的视图。在调用方法一之前会判断当前视图不是是隐藏,用户交互是enable,透明度大于0.01,然后调用方法二,检测触摸点是否在本视图之内,如果不在则不进行方法一,如果在就会用倒叙的方法遍历自己的子视图,让他们走一遍方法二与方法一,如果子视图方法一返回的UIView不为空则让这个UIView处理点击事件,如果他不处理就让他的父视图处理,以此类推,最后都没有视图响应就丢弃。
    3. 事件响应

      1. touchesBegan(Modved)(Ended):withEvent:

    3. 图像显示原理

    设计工作单位

    1. cpu
    2. gpu:涂层渲染,纹理合成
    3. 帧缓冲区:gpu产生的数据
    4. 视频控制器:把帧缓冲去的数据显示到显示器
    5. 显示器

    UI具体显示

    1. CALayer(内容布局等计算)(cpu负责)
    2. Core Animation(cpu负责)
    3. OpenGL(ES)(GPU负责)
    4. Screen

    cpu具体流程

    1. 布局计算(UI布局,文本计算)
    2. 显示计算(drawRect:)
    3. 其他一些准备工作(图片编解码)
    4. 提交内容给GPU(提交位图)

    GPU渲染管线(OpenGL渲染管线)

    1. 顶点着色
    2. 图元装配
    3. 光栅化
    4. 片段着色
    5. 片段处理
    6. 把最终的像素点提交到帧缓冲区中(视频控制器会在VSync(垂直同步)到来时显示在屏幕上)

    4. 卡顿&掉帧

    1. 原因
    2. 解决方案

    1. 原因

    1. 16.7ms产生一帧画面
    2. cpu+gpu提交一次帧缓冲区的时间和小于16.7ms
    3. 时间大于这个时间 就会产生掉帧,卡顿现象

    2. 解决方案

    1. 从cpu
      1. 对象的创建调整销毁(子线程)
      2. 预排版 (布局计算,文本计算)
      3. 预渲染(文本异步绘制,图片编码等)
    2. 从GPU
      1. 纹理渲染(离屏渲染)
      2. 视图混合(视图复杂,减轻视图复杂程度)

    5. 绘制原理&异步绘制

    1. UIView对象调用setNeedsDisplay方法,就会调用他的layer的同名方法
    2. layer标记自己需要在runloop休眠时刷新自身contents-[layer display]
    3. 在刷新自身content算的时候会判断自身的delegate是否响应了displayLayer:方法,如果没有就走系统绘制流程,如果有则走用户自定义的绘制流程(这也是异步绘制的突破点)

    系统绘制流程

    1. CALayer 创建 backing store(CGContextRef)
    2. layer代理没有响应方法
    3. CALayer 调用drawInContext:
    4. CALayer 上传backing store
    5. 结束

    自定义绘制流程

    这个过程要求代理自己生成响应的bitmap(位图),并且把bitmap设置为layer.contents的值。

    1. 会在相应代理方法后调用代理绘制方法
      1. CGBitmapContextCreate()
      2. CoreGraphic API
      3. CGBitmapContextCreateImage()
    2. 回调UIView 的 drawRect:让用户做一些其他自定义的事情
    3. 上传backing store

    6. 离屏渲染-Off-Screen rendering

    1. 相对应的On-Screen Rendering
    2. Off-Screen rendering

    1. 相对应的On-Screen Rendering

    在当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行

    2. Off-Screen rendering

    GPU在当前屏幕缓冲区以外新开辟的一个缓冲区进行渲染操作

    触发条件

    1. 圆角与maskToBounds 一起设置
    2. 图层蒙版
    3. 阴影
    4. 光栅化

    为什么避免

    增加GPU工作量,导致GPU工作时间增长

    1. 新的渲染缓冲区
    2. 上下文的切换

    相关文章

      网友评论

          本文标题:# UI视图相关

          本文链接:https://www.haomeiwen.com/subject/bogesftx.html