2020 iOS面试题记录

1,874 阅读9分钟

GCD中dispatch_async一定会创建线程吗?

注意:**异步执行(async)**虽然具有开启新线程的能力,但是并不一定开启新线程。这跟任务所指定的队列类型有关(下面会讲)。

GCD详尽

dispatch_once的底层实现原理?线程安全吗?为什么?

dispatch_once能保证任务只会被执行一次,即使同时多线程调用也是线程安全的。常用于创建单例、 swizzeld method等功能。它的功能比较简单, dispatch_once用原子性操作block执行完成标记位,同时用信号量确保只有一个线程执行block,等block执行完再唤醒所有等待中的线程。

点击这篇文章可以看到底层实现

NotificationCenter如何实现的

传送

设置圆角一定会触发离屏渲染吗?哪些情况不会触发离屏渲染?UIImageView设置会触发吗?

iOS 离屏渲染探究

iOS 渲染原理解析

CALayer 与 UIView 的关系

UIView 作为最常用的视图控件,和 CALayer 也有着千丝万缕的联系,那么两者之间到底是个什么关系,他们有什么差异?
当然,两者有很多显性的区别,比如是否能够响应点击事件。但为了从根本上彻底搞懂这些问题,我们必须要先搞清楚两者的职责。
根据 Apple 的官方文档,UIView 是 app 中的基本组成结构,定义了一些统一的规范。它会负责内容的渲染以及,处理交互事件。具体而言,它负责的事情可以归为下面三类:

  • Drawing and animation:绘制与动画
  • Layout and subview management:布局与子 view 的管理
  • Event handling:点击事件处理

而从 CALayer 的官方文档中我们可以看出,CALayer 的主要职责是管理内部的可视内容,这也和我们前文所讲的内容吻合。当我们创建一个 UIView 的时候,UIView 会自动创建一个 CALayer,为自身提供存储 bitmap 的地方(也就是前文说的 backing store),并将自身固定设置为 CALayer 的代理。
CALayer UIView 的属性之一,负责渲染和动画,提供可视内容的呈现。
UIView 提供了对 CALayer 部分功能的封装,同时也另外负责了交互事件的处理。

离屏渲染具体过程

通常的渲染流程是这样的:

App 通过 CPU 和 GPU 的合作,不停地将内容渲染完成放入 Framebuffer 帧缓冲器中,而显示屏幕不断地从 Framebuffer 中获取内容,显示实时的内容。

而离屏渲染的流程是这样的:

与普通情况下 GPU 直接将渲染好的内容放入 Framebuffer 中不同,需要先额外创建离屏渲染缓冲区 Offscreen Buffer,将提前渲染好的内容放入其中,等到合适的时机再将 Offscreen Buffer 中的内容进一步叠加、渲染,完成后将结果切换到 Framebuffer 中。

事件是如何传递?

详解

在Application将事件分发到主窗口后就会向下查找最适合处理该事件的视图。 Application事件队列->程序主窗口->向下查找最适合处理事件的View 在查找最合适处理事件的视图过程中有两个非常重要的函数:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;函数是返回可以响应该事件的视图,如果返回不为空则该视图可以处理该事件,相反返回空则不能处理该事件。
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;函数返回产生事件的坐标是否在该视图坐标系中。返回YES,代表产生事件的点在该视图坐标系上,说明该视图可以处理该事件;返回NO,代表产生事件的点不在该视图坐标系中,说明该视图不能处理该事件。

UIWebView和WKWebView是如何与Native通信的,其次是cookie是如何管理的?

  • WebView加载网页得到的Cookie会同步到NSHTTPCookieStorage中(也许你看过一些文章说不能同步,但笔者这里说下,它真的会,大家可以尝试下,实践出真知)。
  • WebView加载请求时,不会同步NSHTTPCookieStorage中已有的Cookie(是的,最坑的地方)。
  • 共用一个WKProcessPool并不能解决2中Cookie同步问题,且可能会造成Cookie丢失。

    WebView Cookie 问题在于 WKWebView 发起的请求不会自动带上存储于 NSHTTPCookieStorage 容器中的 Cookie。

iOS中UIWebView与WKWebView、JavaScript与OC交互、Cookie管理看我就够(上)

iOS中UIWebView与WKWebView、JavaScript与OC交互、Cookie管理看我就够(中)

iOS中UIWebView与WKWebView、JavaScript与OC交互、Cookie管理看我就够(下)

Runloop和AutoRelease的管理

据苹果官方文档中对 NSAutoreleasePool 的描述,我们可知,在主线程的 NSRunLoop 对象(在系统级别的其他线程中应该也是如此,比如通过 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 获取到的线程)的每个 event loop 开始前,系统会自动创建一个 autoreleasepool ,并在 event loop 结束时 drain 。我们上面提到的场景 1 中创建的 autoreleased 对象就是被系统添加到了这个自动创建的 autoreleasepool 中,并在这个 autoreleasepool 被 drain 时得到释放。 另外,NSAutoreleasePool 中还提到,每一个线程都会维护自己的 autoreleasepool 堆栈。换句话说 autoreleasepool 是与线程紧密相关的,每一个 autoreleasepool 只对应一个线程。

要实现 weak ,说白了就是要做到两点:1、引用计数器不变;2、对象销毁后自动设置为 nil。而在 runtime 所提供的枚举中,OBJC_ASSOCIATION_ASSIGN 就已经做到了第一点,我们只需要实现第二点即可。第二点是要在对象销毁后,将 weak 引用设置为 nil ,所以我们要捕获这个对象销毁的时机,或者接收这个对象销毁的事件。在 ARC 中,对象销毁时机其实就是 dealloc 方法调用的时机,我们可以在这个方法里将这个 weak 引用设置为 nil。于是我们可以有下面的思维图:(假设 a.xxx = b,则下图中“宿主对象”就是 a,“某属性”就是 xxx,“值对象”就是 b)

TCP与UDP的区别

TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。 一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂, 只简单的描述下这三次对话的简单过程:

1)主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;

2)主机B向主机A发送同意连接和要求同步 (同步就是两台主机一个在发送,一个在接收,协调工作)的数据包 :“可以,你什么时候发?”,这是第二次对话;

3)主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”, 这是第三次对话。

三次“对话”的目的是使数据包的发送和接收同步, 经过三次“对话”之后,主机A才向主机B正式发送数据。

TCP三次握手过程 第一次握手:主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B,向主机B 请求建立连接,通过这个数据段, 主机A告诉主机B 两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我。

第二次握手:主机B 收到主机A的请求后,用一个带有确认应答(ACK)和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两件事:我已经收到你的请求了,你可以传输数据了;你要用那个序列号作为起始数据段来回应我

第三次握手:主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B 的数据段:"我已收到回复,我现在要开始传输实际数据了,这样3次握手就完成了,主机A和主机B 就可以传输数据了。

3次握手的特点 没有应用层的数据 ,SYN这个标志位只有在TCP建立连接时才会被置1 ,握手完成后SYN标志位被置0。

TCP建立连接要进行3次握手,而断开连接要进行4次 第一次: 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求 ;

第二次: 主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1;

第三次: 由B 端再提出反方向的关闭请求,将FIN置1 ;

第四次: 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.。

由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式, 大大提高了数据通信的可靠性,使发送数据端和接收端在数据正式传输前就有了交互, 为数据正式传输打下了可靠的基础。

UDP(User Data Protocol,用户数据报协议) 1、UDP是一个非连接的协议,传输数据之前源端和终端不建立连接, 当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。 在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、 计算机的能力和传输带宽的限制; 在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

2、 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等, 因此一台服务机可同时向多个客户机传输相同的消息。

3、UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

4、吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、 源端和终端主机性能的限制。

5、UDP使用尽最大努力交付,即不保证可靠交付, 因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

6、UDP是面向报文的。发送方的UDP对应用程序交下来的报文, 在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界, 因此,应用程序需要选择合适的报文大小。

CALayer 与UIView的区别 用CALayer的优点在哪里

UITableView优化

如何快速刷新一个视图

Block的内存管理

内存泄漏在工具查不到的情况下应该注意哪些?

MVVM

自动行高

week是怎么实现的

IM消息如何处理

详解直接点吧