性能是非常模糊的术语,包含应用消耗的内存,节约的网络流量,使用起来流畅度。 大概的性能优化知识点:内存,电量消耗,初始化时间,并发编程,用户界面,网络环境,UItableview。
1. 内存管理
内存:内存涉及运行应用的最小RAM值,以及应用消耗的内存平均值和峰值。同时还要确保没有泄漏内存
内存消耗:应用消耗的RAM,分为堆大小和栈大小。
- 栈大小:应用中新创建的每个线程都有专用的栈空间,栈可以在线程期间自由使用,线程的最大栈空间很小。
可被递归调用的方法数,一个方法中最多可以使用的变量个数,视图层级中可以嵌套的最大视图深度。
- 堆大小:每个进程的所有线程共享一个堆。只有操作系统才能管理堆。通过类创建的对象相关的所有数据都存在堆中。
当对象被创建并被赋值时,数据可能从栈复制到堆
NSString * name =@"xiaoming"; Person * per = [[Person alloc] init]; per.name = name;
。当值仅在方法内部使用时,数据可能从堆复制到栈,NSString * name; Person * per = [[Person alloc] init]; name = per.name;
。
内存管理模型:基于持有关系,当对象没有被任何变量引用(也可以说是没有指针指向该对象)的时候,就会被释放。不细说了,这个展开来讲,涉及的知识点都可以写成一篇长文。
2. 电量消耗
- CPU:应用计算的越多,消耗的电量就越多。相同的基本操作,老一代设备消耗更多的性能。
对数据的处理,执行更新的次数,排序方法(大数据时采用快速排序),从服务器接收数据,减少客户端处理数据量。
- 网络:智能网络管理可以让响应更快,延迟电池寿命。进行网络操作之前,持续监视网络可用性,给予适当策略反馈。蜂窝无线系统对电量的消耗大于wifi。
- 管理定位GPS:关闭无关紧要特性。
- 屏幕:合理休眠,暂停。
- 电量感知:UIDevice的API可以获取battery信息
3. 初始化时间
启动时应执行刚好够用的任务。检查是否为首次启动,检查用户是否登录,检查是否有上次启动挂起的任务等。
4. 并发编程
- 线程创建和启动都有时间开销,而且还都挺大的,创建4~5毫秒,启动20几毫秒。而且消耗的是内存开销,内核内存开销。
- 合理应用GCD,解决线程的创建与管理。GCD线程池上限64个。
5. 用户界面UI
- 最小化更新UI所需的时间,使其接近60帧/s fps。
- 尽可能轻量化VC,创建合理基类VC,VC只是纽带,中介者,而不是存放业务逻辑的地方。使用category创建可复用的代码,VC做绑定数据。层级之间做到组件化。
- 优化VC载入时间,尽量减少主线程工作,避免较大的nibs或故事板,避免多层次嵌套。
- 复杂UI,最好自定义绘图。避免代价较高的
-(void)layoutSubviews{}``- (void)drawRect:(CGRect)rect{}
。涉及到动画还要合理位置的开始停止销毁动画,不做多余操作。
6. 网络环境 https
- 最大成都减少应用发起连接数;
- 减少域名,减少DNS查找时间;
- 请求结束后根据情况不必关闭https,请求头内 connection:keep-alive。
7. UITableview
- 图片处理,采用懒加载图片策略。即在 cell加载方法中,判断有没有缓存好的图片/判断是否停止拖拽/判断加速度为0/或滑动减速,再去执行加载图片。
- 避免渐变图像,缩放以及屏幕外的绘制。CoreGraphics绘制圆角相关。避免透明或alpha低于1的视图。
- 重用单元格时,避免layoutIfNeeded每次重新布局。
- 尽可能避免动态高度,如果用,可以选择较高的单元格,减少计算,缓存动态高度。
- 不要动态创建子视图,可以使用hiden。指定子视图背景色,避免透明或alpa<1。
- cell可以栅格化,将cell所有内容生产一张独立的图像。
self.layer.shouldRasterize = YES;
且设置分辨率。 - 如果cell比较复杂可以设置异步绘制
self.layer.drawsAsynchronously = YES;
。
@end 欢迎指正。