从 Auto Layout 的布局算法谈性能 - iOS 源代码解析 - SegmentFault想要让 iOS 应用的视图保持 60 FPS 的刷新频率,我们必须在1/60 = 16.67 ms之内完成包括布局、绘制以及渲染等操作。
当对30 个左右视图使用 Auto Layout 进行布局时,所需要的时间就会在 16.67 ms 左右,当然这里不排除一些其它因素的影响;到目前为止,会得出一个大致的结论,使用 Auto Layout 对复杂的 UI 界面进行布局时(大于 30 个视图)就会对性能有严重的影响(同时与设备有关,文章中不会考虑设备性能的差异性)
+ load 方法
https://segmentfault.com/a/1190000005025068
如果有分类, 分类的load方法也会被调用.
在main.m文件中, 我并没有对测试类进行任何的引用, 但是依然调用了load方法.
应用:
load可以说我们在日常开发中可以接触到的调用时间最靠前的方法,在主函数运行之前,load方法就会调用。
由于它的调用不是惰性的,且其只会在程序调用期间调用一次,最最重要的是,如果在类与分类中都实现了load方法,它们都会被调用,不像其它的在分类中实现的方法会被覆盖,这就使load方法成为了方法调剂的绝佳时机。
但是由于load方法的运行时间过早,所以这里可能不是一个理想的环境,因为某些类可能需要在在其它类之前加载,但是这是我们无法保证的。不过在这个时间点,所有的 framework 都已经加载到了运行时中,所以调用 framework 中的方法都是安全的。
dyld
dyld是 the dynamic link editor 的缩写,它是苹果的动态链接器。在系统内核做好程序准备工作之后,交由 dyld 负责余下的工作。
OC中的方法存放.
对象方法.
在OC中, 对象的方法并没有存放在对象的结构体中.(如果每一个对象都保存了自己能执行的方法, 那么对内存的占用会非常大的影响)
当实例方法被调用时,它要通过自己持有的isa来查找对应的类,然后在这里的objc_method_list *结构体中查找对应方法的实现。同时,每一个objc_class也有一个指向自己的父类的指针super_class用来查找继承的方法。
类方法?
类方法的实现又是如何查找并且调用的呢?需要引入元类来保证无论是类还是对象都能通过相同的机制查找方法的实现。
让每一个类的isa指向对应的元类,这样就达到了使类方法和实例方法的调用机制相同的目的:
实例方法调用时,通过对象的isa在类中获取方法的实现.
类方法调用时,通过类的isa在元类中获取方法的实现.
所谓高像素就是图片本身并不算大,但是图片宽高非常大的图片.
永远不要直接传递UIImage对象.在需要传递UIImage的场景中,请使用图片名或者NSData二进制对代替.
iOS 中的性能问题大多是阻塞主线程导致用户的交互反馈出现可以感知的延迟。
详细说起来,大体有三种原因:
1. UI 渲染需要时间较长,无法按时提交结果.
2. 一些需要密集计算的处理放在了主线程中执行,导致主线程被阻塞,无法渲染 UI 界面.
3. 网络请求由于网络状态的问题响应较慢,UI 层由于没有模型返回无法渲染.
上面的这些问题都会影响应用的性能,最常见的表现就是UITableView在滑动时没有达到60 FPS,用户能感受到明显的卡顿。
屏幕是如何渲染的?
显示器只是用于将图像显示在屏幕上,谁又是图像的提供者呢?图像都是我们经常说的 GPU 提供的.
而这导致了另一个问题,由于 GPU 生成图像的频率与显示器刷新的频率是不相关的,那么在显示器刷新时,GPU 没有准备好需要显示的图像怎么办;或者 GPU 的渲染速度过快,显示器来不及刷新,GPU 就已经开始渲染下一帧图像又该如何处理?
引入多个缓冲区可以有效地缓解屏幕撕裂,也就是同时使用一个帧缓冲区(frame buffer)和多个后备缓冲区(back buffer);在每次显示器请求内容时,都会从帧缓冲区中取出图像然后渲染。
虽然缓冲区可以减缓这些问题,但是却不能解决;如果后备缓冲区绘制完成,而帧缓冲区的图像没有被渲染,后备缓冲区中的图像就会覆盖帧缓冲区,仍然会导致屏幕撕裂。
解决这个问题需要另一个机制的帮助,也就是垂直同步(Vertical synchronization),简称 V-Sync 来解决。
根据 V-Sync 的原理,优化应用性能、提高 App 的 FPS 就可以从两个方面来入手,优化 CPU 以及 GPU 的处理时间。
性能调优的策略
CPU 和 GPU 在每次 V-Sync 时间点到达之前都在干什么?如果,我们知道了它们各自负责的工作,通过优化代码就可以提升性能。
很多 CPU 的操作都会延迟 GPU 开始渲染的时间:
* 布局的计算 - 如果你的视图层级太过于复杂,或者视图需要重复多次进行布局,尤其是在使用 Auto Layout 进行自动布局时,对性能影响尤为严重;
* 视图的惰性加载 - 在 iOS 中只有当视图控制器的视图显示到屏幕时才会加载;
*解压图片 - iOS 通常会在真正绘制时才会解码图片,对于一个较大的图片,无论是直接或间接使用UIImageView或者绘制到 Core Graphics 中,都需要对图片进行解压;
...
宽泛的说,大多数的CALayer的属性都是由 GPU 来绘制的,比如图片的圆角、变换、应用纹理;但是过多的几何结构、重绘、离屏绘制(Offscrren)以及过大的图片都会导致 GPU 的性能明显降低。
上面的内容出自CPU vs GPU · iOS 核心动画高级技巧,你可以在上述文章中对 CPU 和 GPU 到底各自做了什么有一个更深的了解。
也就是说,如果我们解决了上述问题,就能加快应用的渲染速度,大大提升用户体验。
MRC --- ARC(让ARC文件在MRC的环境下进行ARC编译)
-fobjc-arc
ARC --- MRC(让MRC文件在ARC的环境下进行MRC编译)
-fno-objc-arc