温故而知新
一. GCD和OperationQueue 二. CADisplayLink、NSTimer使用注意 三. 内存布局 四. Tagged Pointer 五. copy和mutableCopy 六. OC对象的内存管理 七. AutoreleasePool自动释放池 八. 图片的解压缩到渲染过程 九. 应用卡顿的原因以及优化 十. APP的启动
GCD 可用于多核的并行运算; GCD 会自动利用更多的 CPU 内核(比如双核、四核); GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程); 程序员只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码。
NSOperation、NSOperationQueue 是基于 GCD 更高一层的封装,完全面向对象。但是比 GCD 更简单易用、代码可读性也更高。
任务和队列不同组合方式的区别
同步和异步主要影响:能不能开启新的线程 同步:在当前线程中执行任务,不具备开启新线程的能力 异步:在新的线程中执行任务,具备开启新线程的能力
并发和串行主要影响:任务的执行方式 并发:多个任务并发(同时)执行 串行:一个任务执行完毕后,再执行下一个任务
面试题
iOS程序的内存布局
Tagged Pointer优化NSNumber示例
copy和mutableCopy
引用计数的存储
dealloc
AutoreleasePool(自动释放池) 是OC中的一种内存自动回收机制,在释放池中的调用了autorelease方法的对象都会被压在该池的顶部(以栈的形式管理对象)。当自动释放池被销毁的时候,在该池中的对象会自动调用release方法来释放资源,销毁对象。以此来达到自动管理内存的目的。
自动释放池的结构
__AtAutoreleasePool 实际是一个结构体,在内部首先执行objc_autoreleasePoolPush(),然后在调用objc_autoreleasePoolPop(atautoreleasepoolobj)。
struct __AtAutoreleasePool {
__AtAutoreleasePool() {
//构造函数,在创建结构体时调用
atautoreleasepoolobj = objc_autoreleasePoolPush();
}
~__AtAutoreleasePool() {
//析构函数,在结构体销毁的时候调用
objc_autoreleasePoolPop(atautoreleasepoolobj);
}
void * atautoreleasepoolobj;
};
AutoreleasePoolPage的结构
AutoreleasePoolPage
Autorelease何时释放? 1、手动调用AutoreleasePool的释放方法(drain方法) 2、Autorelease对象是在当前的runloop迭代结束时释放的,而它能够释放的原因是系统在每个runloop迭代中都加入了自动释放池Push和Pop
Runloop和Autorelease的关系
Runloop和Autorelease
总结:图片渲染到屏幕的过程: 读取文件->计算Frame->图片解码->解码后纹理图片位图数据通过数据总线交给GPU->GPU获取图片Frame->顶点变换计算->光栅化->根据纹理坐标获取每个像素点的颜色值(如果出现透明值需要将每个像素点的颜色*透明度值)->渲染到帧缓存区->渲染到屏幕
CPU: 计算视图frame,文本计算和排版,图片解码,需要绘制纹理图片通过数据总线交给GPU。 GPU: 纹理混合,顶点变换与计算,像素点的填充计算,渲染到帧缓冲区。 平时所说的“卡顿”主要是因为在主线程执行了比较耗时的操作, 可以添加Observer到主线程RunLoop中,通过监听RunLoop状态切换的耗时,以达到监控卡顿的目的。
屏幕呈像原理
卡顿产生的原因
在 VSync 信号到来后,系统图形服务会通过 CADisplayLink 等机制通知 App,App 主线程开始在 CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等。随后 CPU 会将计算好的内容提交到 GPU 去,由 GPU 进行变换、合成、渲染。随后 GPU 会把渲染结果提交到帧缓冲区去,等待下一次 VSync 信号到来时显示到屏幕上。由于垂直同步的机制,如果在一个 VSync 时间内,CPU 或者 GPU 没有完成内容提交,则那一帧就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。这就是界面卡顿的原因。 从上面的图中可以看到,CPU 和 GPU 不论哪个阻碍了显示流程,都会造成掉帧现象。所以开发时,也需要分别对 CPU 和 GPU 压力进行评估和优化。
CPU
GPU
离屏渲染
APP的冷启动可以概括为3大阶段:dyld、runtime、main
dyld(dynamic link editor),Apple的动态链接器,可以用来装载Mach-O文件(可执行文件、动态库等)。 启动APP时,dyld所做的事情有:
启动APP时,runtime所做的事情有:
接下来就是UIApplicationMain函数,AppDelegate的application:didFinishLaunchingWithOptions:方法
APP启动优化