Skip to content

1.UIButton继承关系是怎样的?

UIButton -> UIControl -> UIView -> UIResponder -> NSObject

2.CALayer和UIView的区别和联系

UIView是在UIKit框架中,封装了CALayer并提供了额外的功能,比如响应事件、布局管理、视图添加移除、参与响应链等。 CALayer是在底层的Core Animation框架中,主要进行内容绘制和动画操作。

3.事件传递、响应者链条、hitTest和pointInside

参考链接:iOS | 事件传递及响应链 iOS | 响应链及手势识别
事件传递(hitTest)是从父视图到子视图,即UIApplication -> UIWindow -> Root View -> ... -> subviews
响应者:继承UIResponder的对象称之为响应者对象,能够处理touchesBegan等触摸事件
响应者链条:由很多响应者链接在一起组合起来的一个链条称之为响应者链条,响应顺序:
Initial View -> View Controller(如果存在) -> superview -> · ·· -> rootView -> UIWindow -> UIApplication

hitTest底层实现:

objective-c
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    // 1.判断自己能否接收触摸事件
    if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
    // 2.判断触摸点在不在自己范围内
    if (![self pointInside:point withEvent:event]) return nil;
    // 3.从后往前遍历自己的子控件,看是否有子控件更适合响应此事件
    int count = self.subviews.count;
    for (int i = count - 1; i >= 0; i--) {
        UIView *childView = self.subviews[i];
        CGPoint childPoint = [self convertPoint:point toView:childView];
        UIView *fitView = [childView hitTest:childPoint withEvent:event];
        if (fitView) {
            return fitView;
        }
    }
    // 没有找到比自己更合适的view
    return self;
}

总的来说,触摸屏幕后事件的传递可以分为以下几个步骤:

1.通过「命中测试」来找到「第一响应者」
2.由「第一响应者」来确定「响应链」
3.将事件沿「响应链」传递
4.事件被某个响应者接收,或没有响应者接收从而被丢弃

4.UI图像显示原理

  1. CPU:计算视图frame,图片解码
  2. GPU:绘制纹理,纹理混合,顶点变换,渲染到帧缓冲区

5.哪些情况会触发离屏渲染

1.圆角设置,当和maskToBounds一起使用的时候
2.阴影属性(shadow)操作时候
3.渐变背景:当视图的背景色设置为渐变色时
4.毛玻璃效果:当使用UIVisualEffectView添加毛玻璃效果时
5.使用mask属性:当使用CALayer的mask属性来设置遮罩效果时

【缺点】:离屏渲染会增加系统资源的消耗,可能导致性能下降,因此在开发过程中应尽量避免不必要的离屏渲染操作。图像不是直接绘制到屏幕上,而是先绘制到一个离屏缓冲区(offscreen buffer)中。完成所有离屏缓冲区中的渲染工作后,再将其内容复制到屏幕上的显示缓冲区(onscreen buffer)。

离屏渲染和非离屏渲染的区别,以及离屏渲染带来的性能问题:

离屏渲染(Offscreen Rendering)

  • 渲染位置:离屏渲染是指图像首先被绘制到一个离屏缓冲区(offscreen buffer)中,而不是直接绘制到屏幕上的显示缓冲区(onscreen buffer)。
  • 上下文切换:由于需要在离屏缓冲区和显示缓冲区之间进行上下文切换,这会增加额外的开销。每次切换都涉及GPU上下文的改变,这需要时间和计算资源。
  • 内存消耗:离屏缓冲区需要额外的内存来存储中间渲染结果,这会增加内存的使用。
  • 渲染时间增加:离屏渲染需要额外的步骤,这会增加渲染时间,可能导致帧率下降,影响用户体验。

非离屏渲染(Onscreen Rendering)

  • 渲染位置:非离屏渲染是指图像直接被绘制到屏幕上的显示缓冲区中。
  • 无上下文切换:因为直接绘制到显示缓冲区,不存在GPU上下文的切换,渲染过程更为高效。
  • 内存消耗较低:没有额外的离屏缓冲区,因此内存消耗较低。
  • 渲染时间较短:渲染步骤较少,通常渲染时间较短,有助于保持较高的帧率和流畅的用户体验。

【为什么存在】:尽管离屏渲染会带来性能消耗,但在一些情况下,为了实现更好的视觉效果和用户体验,开发者可能会选择使用离屏渲染。在实际开发中,需要权衡视觉效果和性能消耗之间的关系,尽量减少不必要的离屏渲染操作,提高应用的性能和用户体验。

6.UI的绘制原理和异步绘制

UI的绘制原理主要涉及以下几个方面:

视图层级结构:iOS应用的UI是通过视图层级结构来组织的,每个视图都有一个对应的CALayer对象负责绘制和渲染。
视图的绘制流程:当视图需要进行绘制时,系统会触发绘制流程。视图的绘制是由底层的Core Graphics框架提供支持的,通过绘制上下文(Graphics Context)来进行绘制操作。
绘制的触发时机:视图的绘制可以在多种时机触发,比如视图第一次显示时、视图的内容发生变化时、调用setNeedsDisplay方法时等。

异步绘制是为了提高性能和流畅度而引入的一种机制,主要包括以下几个方面:

异步绘制线程:为了避免在主线程中进行耗时的绘制操作,iOS引入了异步绘制线程,将视图的绘制操作放到子线程中进行,避免阻塞主线程。
异步绘制的优化:异步绘制可以通过多线程、队列等技术来实现,可以提高绘制的效率和性能。
异步绘制的应用:异步绘制常用于复杂视图或需要大量绘制操作的场景,可以提高应用的响应速度和用户体验。
总的来说,UI的绘制原理涉及视图层级结构和绘制流程,而异步绘制是为了提高性能和流畅度而引入的一种机制,通过将绘制操作放到子线程中进行,可以提高应用的性能和用户体验。

世界很美 而你正好有空