instrument 分析:
参考文档:
1.http://www.jianshu.com/p/9e1f0b44935c
2.http://www.open-open.com/lib/view/open1421115558515.html
使用文档:
http://cdn.cocimg.com/bbs/attachment/Fid_6/6_24457_90eabb4ed5b3863.pdf
关于性能优化的25个建议和技巧:
http://blog.jobbole.com/37984/
性能优化:
启动时间、用户响应(UI反馈响应及时)、列表滚动操作流畅、图形动画、内存使用合理、不会随便crash。
1.NSDateFormatter
创建耗时33ms ,NSDateFormatter 设置3个属性平均耗时也在30ms左右,NSCalendar与之类似。
解决方案:尽量避免采用处理多个日期格式,当然针对日期格式处理如果需要提高更多的速度,可以直接采用C,可以菜用https://blog.soff.es/how-to-drastically-improve-your-app-with-an-afternoon-and-instruments来规避这个问题。
2.UIImage缓存取舍
imagedNamed 初始化:默认加载图片成功后会在内存中缓存图片,这个方法用一个指定的名字在系统缓存中查找并返回一个图片对象。如果缓存中没有找到形影的图片对象,则从指定地方加载图片然后缓存对象,并返回这个图片对象。
imagedWithContentsOfFile初始化:仅加载图片,不缓存。
解决方案:
大量使用imageNamed方式会在不需要缓存的地方额外增加开销CPU的时间来哦做这件事,当应用程序需要加载一张比较大的图片并且使用一次性,那么其实是没有必要去缓存这个图片的,用imageWithContentsOfFile是最为经济的方式,这样不会因为UIImage元素较多情况下,CPU会被逐个分散在不必要缓存上浪费过多时间。
3.对于不一定展示的而且费时UI尽量采用多线程,将必须展示的UI放在主线程中,而不一定展示的UI放在子线程中
另外针对单个view 尽量不要在viewWillAppear费时的操作,viewWillAppear在 view 显示之前被调用,出于效率考虑,在这个方法中不要处理复杂费时的事情;只应该在这个方法设置 view 的显示属性之类的简单事情,比如背景色,字体等。不然,用户会明显感觉到 view 显示迟钝。
4.避免首次加载耗时
应用程序首次加载中启动方法willFinishLaunchingWithOptions和didFinishLaunchingWithOptions只做应用程序首次启动必须的要操作,而针对_dyid_start在初始化库framework函数的操作.不必要的Framework不要链接,避免首次加载耗时。
5.尽量把views设置为不透明
如果你有不透明的Views,你应该设置它们的opaque属性为YES。原因是这会使系统用一个最优的方式渲染这些views。
(opaque)这个属性给渲染系统提供了一个如何处理这个view的提示。如果设为YES, 渲染系统就认为这个view是完全不透明的,这使得渲染系统优化一些渲染过程和提高性能。如果设置为NO,渲染系统正常地和其它内容组成这个View。
在模拟器中用Debug\Color Blended Layers选项来发现哪些view没有被设置为opaque。目标就是,能设为opaque的就全设为opaque!
6.避免过于庞大的XIB
iOS5中加入的Storyboards(分镜)正在快速取代XIB。然而XIB在一些场景中仍然很有用。比如你的app需要适应iOS5之前的设备,或者你有一个自定义的可重用的view,你就不可避免地要用到他们。
如果你不得不XIB的话,使他们尽量简单。尝试为每个Controller配置一个单独的XIB,尽可能把一个View Controller的view层次结构分散到单独的XIB中去。
需要注意的是,当你加载一个XIB的时候所有内容都被放在了内存里,包括任何图片。如果有一个不会即刻用到的view,你这就是在浪费宝贵的内存资源了。Storyboards就是另一码事儿了,storyboard仅在需要时实例化一个view controller。
7.不要阻塞主线程
永远不要使主线程承担过多。因为UIKit在主线程上做所有工作,渲染,管理触摸反应,回应输入等都需要在它上面完成。一直使用主线程的风险就是如果你的代码真的block了主线程,你的app会失去反应。
大部分阻碍主进程的情形是你的app在做一些牵涉到读写外部资源的I/O操作,比如存储或者网络。
你可以使用NSURLConnection异步地做网络操作:
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler或者使用像AFNetworking这样的框架来异步地做这些操作。
如果你需要做其它类型的需要耗费巨大资源的操作(比如时间敏感的计算或者存储读写)那就用 Grand Central Dispatch,或者 NSOperation 和 NSOperationQueues。
8.在Image Views中调整图片大小
如果要在UIImageView中显示一个来自bundle的图片,你应保证图片的大小和UIImageView的大小相同。在运行中缩放图片是很耗费资源的,特别是UIImageView嵌套在UIScrollView中的情况下。
如果图片是从远端服务加载的你不能控制图片大小,比如在下载前调整到合适大小的话,你可以在下载完成后,最好是用background thread,缩放一次,然后在UIImageView中使用缩放后的图片。
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg:
在后台执行一个操作,本质就是重新创建一个线程执行当前方法。
9.选择正确的Collection!?
学会选择对业务场景最合适的类活着对象是写出能效高的代码的基础。
一些常见Collection的总结:
Arrays: 有序的一组值。使用index来lookup很快,使用value lookup很慢, 插入/删除很慢。
Dictionaries: 存储键值对。 用键来查找比较快。
Sets: 无序的一组值。用值来查找很快,插入/删除很快。
10.打开gzip压缩??
iOS已经在NSURLConnection中默认支持了gzip压缩,当然AFNetworking这些基于它的框架亦然。像Google App Engine这些云服务提供者也已经支持了压缩输出。
11.优化TableView
为了保证table view平滑滚动,确保你采取了以下的措施:
正确使用reuseIdentifier来重用cells
尽量使所有的view opaque,包括cell自身
避免渐变,图片缩放,后台选入
缓存行高
如果cell内显示的内容来自web,使用异步加载,缓存请求结果
使用shadowPath来画阴影
减少subviews的数量
尽量不使用cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果
使用正确的数据结构来存储数据
使用rowHeight,sectionFooterHeight和sectionHeaderHeight来设定固定的高,不要请求delegate