iOS开发之性能优化
1.避免过于庞大的XIB
当加载XIB的时候把所有的东西都放在了内存里,包括任何的图片;如果有一个不会即刻用到的view,就会浪费宝贵的内存资源了。
当加载一个引用了图片或者声音资源的nib时,nib加载代码会把图片和声音文件写进内存。
2.不要阻塞主线程
UIKit在主线程上的所有工作,渲染,管理触摸,回应输入等都需要在上面完成。
将耗时操作放在子线程中。
3.在imageViews中调整图片的大小
如果要在UIImageView中显示一个来自bundle的图片,你就应该保证图片的大小和UIImageView的大小相同。在运行中缩放图片是很耗费资源的,特别是UIImageView嵌套在UIScrollView中的情况下。
如果是从远程服务器加载,本地无法控制图片的大小。应该在下载完成 后,最好用background thread,缩放一次,然后在UIImageView中使用缩放后的图片。
4.选择正确的collection
Arrays:有序的一组值。使用index来lookup很快,使用value lookup很慢,插入/删除很慢。
Dictionaries:存储键值对。用值来查找比较快。
Sets:无序的一组值。用值来查找很快,插入/删除很快。
5.重用或者延迟加载Views
如点击一个按钮需要呈现一个view的场景。
第一种:创建并隐藏这个view当这个screen加载的时候,当需要时显示它。(更加耗内存)
第二各:当需要时才创建并展示。(比上一种慢)
6.Cache,Cache,还是Cache!
Cache所需要Cache的(也就是那些不大可能改变但是需要经常读取的东西)
7.权衡渲染的方法
简单来说,就是用事先渲染好的图片更快一些,因为如此一来iOS就免去了创建一个图片再画东西上去然后显示在屏幕上的程序。问题是你需要把所有你需要用到的图片放到app的bundle里面,这样就增加了体积 – 这就是使用可变大小的图片更好的地方了: 你可以省去一些不必要的空间,也不需要再为不同的元素(比如按钮)来做不同的图。
然而,使用图片也意味着你失去了使用代码调整图片的机动性,你需要一遍又一遍不断地重做他们,这样就很浪费时间了,而且你如果要做一个动画效果,虽然每幅图只是一些细节的变化你就需要很多的图片造成bundle大小的不断增大。
总得来说,你需要权衡一下利弊,到底是要性能能还是要bundle保持合适的大小。
8.重用重大开销对象
想要避免使用这个对象的瓶颈你就需要重用他们,可以通过添加属性到你的class里或者创建静态变量来实现。
注意如果你要选择第二种方法,对象会在你的app运行时一直存在于内存中,和单例(singleton)很相似。
9.避免反复处理数据
比如需要数据来展示一个tableView,最好直播从服务器取array结构的数据以避免的额外的中间数据结构改变。
如果需要从特定的key中取数据,那么就使用键值对的dictionary;
10.正确设定背影图片
使用UIColor的colorWithPatternImage来设置背景色;
在view中添加一个UIImageView作为一个子View;
如果你使用全画幅的背景图,你就必须使用UIImageView因为UIColor的colorWithPatternImage是用来创建小的重复的图片作为背景的。
如果你用小图平铺来创建背景,你就需要用UIColor的colorWithPatternImage来做了,它会更快地渲染也不会花费很多内存
11.优化Table View
正确使用reuseIdentifier来重用cells
尽量使所有的view opaque,包括cell自身
避免渐变,图片缩放,后台选人
缓存行高
如果cell内现实的内容来自web,使用异步加载,缓存请求结果
使用shadowPath来画阴影
减少subviews的数量
尽量不适用cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果
使用正确的数据结构来存储数据
尽量使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight来设定固定的高,不要请求delegate
12.使用正确的数据存储选项
使用NSUserDefaults(只能存一些小型数据,比如一些简单的布尔型的设置选项)
使用XML,JSON或者plist(需要读取文件到内存里去解析,这样是很不经济的)
NSCoding(也是文件读写,也有上述问题)
Sqlite(可以存储大数据)
13.加快启动时间
尽可能做更多的异步任务
避免使用庞大的XIB,因为他们是在主线程上加载,尽量使用Storyboards.(必须把设备从Xcode断开来测试启动速度)
14.使用Autorelease Pool
创建多个临时对象,发现内存一直减少,直到这些对象被release的时候,这是因为只有当autorelease pool的时候memory才会被释放。