1 App的编译过程
现在工程基本都是Pod进行管理的,就以Pod工程举例。
1,因为主工程依赖了Pod工程,所以先编译Pod工程,生成framewrok
2,生产hmap文件来搜索头文件,创建.app目录
3,处理entitlements.plist文件
4,执行主工程的脚本,运行校验Pod脚本
5,按照Compile Sources里面的顺序编译主工程代码,并链接
6,运行复制脚本,复制framework或者bundle的资源到App目录里面
7,编译storyboard、xib
8,编译asset文件
9,复制并压缩png图片文件
10,复制swift标准库文件
11,对包进行签名
2 Notificaiton/Block/Delegate/Target-Action/KVO
Delegate比较严谨、规范,较强的代码可读性。要先声明、再实现,比较繁琐,适合调用方法比较多的情况。但需要注意循环引用。跨层使用比较困难。容易调试。
Block 简单易用,代码都统一在一个地方,容易理解。适合调用方法比较少的情况。比如简单的完成回调、按钮的点击等。需要注意强引用的情况。
Notification 一个对象发出的通知,多个对象能进行反应,适合一对多的场景,特别是当业务层级比较深的时候。编译期无法验证正确性,因此注意字符串的正确性。不方便调试、代码的可读性差
KVO 多用于1对1的场景,可以完成其他几个实现不了的事情,比如scrollView的contentOffset。但使用起来比较麻烦,需要注册,不用时需要移除,且编译时无法验证注册的正确性。不方便调试、代码的可读性差
3 HTTPS
TCP三次握手结束后,开始HTTPS握手,端口是443。
客户端向服务端端发送Client Hello数据包(包含支持的TLS版本、支持的加密套件、支持的压缩算法、SessionID、扩展信息(如SNI Server Name Indication)等基础信息,以及一个随机数 random_num_client)。因为此时还没有开始HTTP请求,故服务端不知道要请求的域名,在多域名的情况下,无法处理证书,SNI用来指明此次请求的域名,类似于请求头的Host。可以让服务端返回具体对应的证书。
服务端在收到Client Hello后会向客户端发送Server Hello数据包(包含最终协议版本、使用的加密套件,以及一个随机数 random_num_server(如果设置了双向校验相关选项,这里server还会向client发送ClientCertificateRequest,后续会校验)。
server_certificates 发送服务端的证书,用于身份验证和密钥交换。
server_hello_done,通知客户端 server_hello 信息发送结束。
客户端收到证书后,进行验证,通过后会使用RSA或DH算法生成第三个随机数(称之为Premaster)然后使用证书公钥加密后发送给服务端。
client和server都知道这三个随机数,且Premaster 在传输过程中是加密的。利用这三个随机数生成MasterSecret进而后续数据传输中使用的,我们用下面这张图来表示
hello阶段,加密使用的是RSA(非对称,安全性高),确定密钥后,传输数据时加密用的是对称密钥(速度快)。
6 dyld![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/31c0b7f54925681880df4a811b1e493f.webp?x-image-process=image/format,png#pic_center)
4 push与pop时的调用顺序
A push 到 B为例
A:viewWillDisappear
B:viewWillAppear
A:viewDidDisappear
B:viewDidAppear
B pop 回 A时
B:viewWillDisappear
A:viewWillAppear
B:viewDidDisappear
A:viewDidAppear
A present B 为例
A:viewWillDisappear
B:viewWillAppear
B:viewDidAppear
A:viewDidDisappear
B dismiss时
B:viewWillDisappear
A:viewWillAppear
A:viewDidAppear
B:viewDidDisappear
5 present viewController
1,每个viewController都有两个属性:presentedViewController和presentingViewController。前者是自己present出的viewController,而后者是present了自己的viewController。
2,一个viewController不能被present两次,在viewDidLoad时也不能present 一个viewController,因为当前的view还没有加入到window的层级。
3,当一个viewController 调用了dismsiss方法时,会先判断是否其presentedViewController是否存在,存在则将其presentedViewController dismiss掉。如果没有则将其身dismiss掉。对于存在多层present的情况,A->B->C->D。当B调用了dismiss方法时,C和D都会被dismiss掉,即便animated为YES,但只有D会有动画。C调用dismiss和D调用dismiss效果一样,都是D被dismiss掉。
6 渲染与绘制
其中Commit Transaction分为
Layout,阶段主要进行视图构建,包括:LayoutSubviews 方法的重载,addSubview: 方法填充子视图等,Autolayout 太多会影响这部分时间。UIViewController的viewDidLayoutSubviews,UIView的layoutSubviews,CALayer的layoutSublayers。
Display, 阶段主要进行视图绘制,这里仅仅是设置最要成像的图元数据。重载视图的 drawRect: 方法可以自定义 UIView 的显示,其原理是在 drawRect: 方法内部绘制寄宿图,该过程使用 CPU 和内存。
Prepare,图片解码发生在这一步。
Commit,将渲染数据打包发给 RenderServer,该过程会递归执行,因为图层和视图都是以树形结构存在。