iOS最全机能优化之25个建议
跳槽求职群:138269539
作者:HelloYeah
机能对 iOS 利用的开辟特别首要,如果你的利用落空反应或很慢,绝望的用户会在App Store写满差评。但是因为iOS装备的限定,偶然搞好机能是一件难事。开辟过程中你会有很多需求重视的事项,也很容易在做出挑选时健忘考虑机能影响。本文针对不合阶段开辟者提出了25个机能优化建议
初学者机能晋升这个部分努力于一些能进步机能的根基改变。但所有层次的开辟者都有可能会从这个记录了一些被忽视的项目标小小的机能备忘录里获得一些晋升。
1.用ARC办理内存
ARC(Automatic Reference Counting, 主动援引计数)和iOS5一路公布,它避免了最多见的也就是常常是因为我们健忘开释内存所酿成的内存泄漏。它主动为你办理retain和release的过程,所以你就没必要去手动干预了。下面是你会经常常利用往来来往建立一个View的代码段:
忘失落代码段末端的release的确像记得用饭一样简朴。而ARC会主动在底层为你做这些事情。除帮你避免内存泄漏,ARC还可以帮你进步机能,它能包管开释失落不再需求的工具的内存。这都啥年代了,你应当在你的所有项目里利用ARC!
2.在精确的处所利用 reuseIdentifier
3.尽可能把views设置为不透明
4. 避免过于庞年夜的XIB
5. 不要梗阻主线程
6. 在Image Views中调剂图片年夜小
7. 挑选精确的Collection
学会挑选对业务场景最适合的类或工具是写出能效高的代码的根本。当措置collections时这句话特别精确。
Apple有一个 Collections Programming Topics 的文档详确介绍了可用的classes间的不同和你该在哪些场景中利用它们。这对任何利用collections的人来讲是一个必读的文档。呵呵,我就晓得你因为太长没看…这是一些常见collection的总结:
8. 翻开gzip紧缩
9. 重用和延迟加载(lazy load) Views
更多的view意味着更多的衬着,也就是更多的CPU和内存耗损,对那种嵌套了很多view在UIScrollView里边的app更是如此。这里我们用到的技能就是仿照UITableView和UICollectionView的操纵: 不要一次建立所有的subview,而是当需求时才建立,当它们完成了任务,把他们放进一个可重用的队列中。如许的话你就只需求在动弹产生时建立你的views,避免了不划算的内存分派。建立views的能效问题也合用于你app的别的方面。想象一下一个用户点击一个按钮的时候需求闪现一个view的场景。有两种实现体例:
每个计划都有其优错误谬误。用第一种计划的话因为你需求一开端就建立一个view并保持它直到不再利用,这就会更加耗损内存。但是这也会使你的app操纵更敏感因为当用户点击按钮的时候它只需求改变一下这个view的可见性。第二种计划则相反-耗损更少内存,但是会在点击按钮的时候比第一种稍显卡顿。
10. Cache, Cache, 还是Cache!
一个极好的准绳就是,缓存所需求的,也就是那些不年夜可能改变但是需求常常读取的东西。我们能缓存些甚么呢?
一些选项是,远端办事器的呼应,图片,乃至计较成果,比如UITableView的行高。NSURLConnection默许会缓存资本在内存或存储中按照它所加载的HTTP Headers。你乃至可以手动建立一个NSURLRequest然后使它只加载缓存的值。下面是一个可用的代码段,你可以可以用它去为一个根基不会改变的图片建立一个NSURLRequest并缓存它:
重视你可以经由过程 NSURLConnection 获得一个URL request, AFNetworking也一样的。如许你就没必要为采取这条tip而改变所有的networking代码了。如果想体味更多关于HTTP caching, NSURLCache, NSURLConnection的相关知识,可以读下这篇文章()如果你需求缓存别的不是HTTP Request的东西,你可以用NSCache。NSCache和NSDictionary近似,不合的是体系收受领受内存的时候它会主动删失落它的内容。
11. 衡量衬着体例
在iOS中可以有很多体例做出标致的按钮。你可以用整幅的图片,可调年夜小的图片,uozhe可以用CALayer, CoreGraphics乃至OpenGL来画它们。当然每个不合的处理体例都有不合的复杂水安然平静呼应的机能。有一篇Apple UIKit team中的一员Andy Matuschak保举过的很棒的关于graphic机能的帖子很值得一读。
12. 措置内存警告
一旦体系内存太低,iOS会告诉所有运行中app。在官方文档中是如许记叙:如果你的app收到了内存警告,它就需求尽可能开释更多的内存。最好体例是移除对缓存,图片object和其他一些可以重修立的objects的strong references.荣幸的是,UIKit供应了几种汇集低内存警告的体例:
一旦收到这类告诉,你就需求开释任何不需求的内存利用。比方,UIViewController的默许行动是移除一些不成见的view, 它的一些子类则可以弥补这个别例,删失落一些分外的数据布局。一个有图片缓存的app可以移除不在屏幕上显现的图片。如许对内存警报的措置是很需求的,若不正视,你的app便可能被体系杀失落。但是,当你必然要确认你所挑选的object是可以被重现建立的来开释内存。必然要在开辟顶用摹拟器中的内存提示摹拟去测试一下。
13. 重用年夜开消工具
一些objects的初始化很慢,比如NSDateFormatter和NSCalendar。但是,你又不成避免地需求利用它们,比如从JSON或XML中剖析数据。想要避免利用这个工具的瓶颈你就需求重用他们,可以经由过程增加属性到你的class里或建立静态变量来实现。重视如果你要挑选第二种体例,工具会在你的app运行时一向存在于内存中,和单例(singleton)很类似。下面的代码说了然利用一个属性来延迟加载一个date formatter. 第一次调用时它会建立一个新的实例,今后的调用则将前往已建立的实例:
还需求重视的是,其实设置一个NSDateFormatter的速率差不多是和建立新的一样慢的!所以如果你的app需求常常进行日期格局措置的话,你会从这个别例中获得不小的机能晋升。
14. 利用Sprite Sheets
你是一个游戏开辟者吗,那么Sprite sheets必然是一个你的最好的朋友了。Sprite sheet可让衬着速率加快,乃至比标准的屏幕衬着体例节流内存。我们有两个很好的关于Sprite的教程:
第二个教程涵盖了可能在很年夜程度上影响你游戏机能的pixel格局的细节。如果你对spirte sheet还不是很熟谙,可以看下这两个(youtube)视频SpriteSheets – The Movie, Part 1 和Part 2。视频的作者是建立Sprite sheet很风行的东西之一Texture Packer的作者Andreas L?w。除利用Sprite sheets,别的写在这里的建议当然也能够用于游戏开辟中。比如你需求很多的Sprite sheets,像仇敌,导弹之类的行动类必备元素,你可以重用这些sprites而不消每次都要从头建立。
15. 避免几次措置数据
很多利用需求从办事器加载服从所需的常为JSON或XML格局的数据。在办事器端和客户端利用不异的数据布局很首要。在内存中操纵数据使它们满足你的数据布局是开消很年夜的。
比如你需求数据来揭示一个table view,最好直接从办事器取array布局的数据以避免分外的中间数据布局改变。近似的,如果需求从特定key中取数据,那么就利用键值对的dictionary。
16. 挑选精确的数据格局
从app和收集办事间传输数据有很多计划,最多见的就是JSON和XML。你需求挑选对你的app来讲最适合的一个。
17. 精确设定背景图片
在View里放背景图片就像很多别的iOS编程一样有很多体例:
如果你利用全画幅的背景图,你就必须利用UIImageView因为UIColor的colorWithPatternImage是用来建立小的反复的图片作为背景的。这类景象下利用UIImageView可以节俭很多的内存:
如果你用小图平铺来建立被页粳你就需求用UIColor的colorWithPatternImage来做了,它会更快地衬着也不会破钞很多内存:
18. 减少利用Web特性
UIWebView很有效,用它来揭示网页内容或建立UIKit很难做到的动画结果是很简朴的一件事。
但是你可能有重视到UIWebView其实不像驱动Safari的那么快。这是因为以JIT compilation 为特性的Webkit的Nitro Engine的限定。
所以想要更高的机能你就要调剂下你的HTML了。第一件要做的事就是尽可能移除不需求的javascript,避免利用过年夜的框架。能只用原生js就更好了。别的,尽可能异步加载比方用户行动统计script这类不影响页面表达的javascript。
最后,永久要重视你利用的图片,包管图片的适合你利用的年夜小。利用Sprite sheet进步加载速率和节俭内存。更多相关信息可以看下 WWDC 2012 session #601 – Optimizing Web Content in UIWebViews and Websites on iOS
19. 设定Shadow Path
如安在一个View或一个layer上加一个shadow呢,QuartzCore框架是很多开辟者的挑选:
看起来很简朴,对吧。但是,坏动静是利用这个别例也有它的问题… Core Animation不克不及不先在背景得出你的图形并加好暗影然后才衬着,这开消是很年夜的。利用shadowPath的话就避免了这个问题:
view.layer.shadowPath = [[UIBezierPath bezierPathWithRect:view.bounds] CGPath];
利用shadow path的话iOS就没必要每次都计较若何衬着,它利用一个事后计较好的途径。但问题是本身计较path的话可能在某些View中比较坚苦,且每当view的frame转变的时候你都需求去update shadow path.想体味更多可以看看Mark Pospesel的这篇。
20. 优化Table View
Table view需求有很好的动弹机能,不然用户会在动弹过程中发明动画的瑕疵。为了包管table view光滑动弹,确保你采纳了以下的办法:
21. 挑选精确的数据存储选项
NSUserDefaults的问题是甚么?固然它很nice也很便利,但是它只合用于小数据,比如一些简朴的布尔型的设置选项,再年夜点你就要考虑别的体例了。XML这类布局化档案呢?团体来讲,你需求读取全部文件到内存里去剖析,如许是很不经济的。利用SAX又是一个很费事的事情。NSCoding?不幸的是,它也需求读写文件,所以也有以上问题。
当存储年夜块数据时,以上的体例都不合用. 在这类利用处景下,利用SQLite 或 Core Data比较好。利用这些技术你用特定的查询语句就可以只加载你需求的工具。在机能层面来讲,SQLite和Core Data是很类似的。他们的不合在于详细利用体例。Core Data代表一个工具的graph model,但SQLite就是一个DBMS。Apple在一般环境下建议利用Core Data,但是如果你有来由不利用它,那么就去利用更加底层的SQLite吧。
22. 加快启动时候
疾速翻开app是很首要的,特别是用户第一次翻开它时,对app来讲,第一印象太太太首要了。
你能做的就是使它尽可能做更多的异步任务,比如加载远端或数据库数据,剖析数据。还是那句话,避免过于庞年夜的XIB,因为他们是在主线程上加载的。所以尽可能利用没有这个问题的Storyboards吧!重视,用Xcode debug时watchdog其实不运行,必然要把装备从Xcode断开来测试启动速率。
23. 利用Autorelease Pool
NSAutoreleasePool卖力开释block中的autoreleased objects。一般环境下它会主动被UIKit调用。但是有些状况下你也需求手动去建立它。
假定你建立很多临时工具,你会发明内存一向在减少直到这些工具被release的时候。这是因为只需当UIKit用光了autorelease pool的时候memory才会被开释。
好动静是你可以在你本身的@autoreleasepool里建立临时的工具来避免这个行动:
这段代码在每次遍历后开释所有autorelease工具更多关于NSAutoreleasePool请参考官方文档。
24. 挑选是不是缓存图片
常见的从bundle中加载图片的体例有两种,一个是用imageNamed,二是用imageWithContentsOfFile,第一种比较常见一点。既然有两种近似的体例来实现不异的目标,那么他们之间的不同是甚么呢?
imageNamed的长处是当加载时会缓存图片。imageNamed的文档中这么说:这个别例用一个指定的名字在体系缓存中查找并前往一个图片工具如果它存在的话。如果缓存中没有找到呼应的图片,这个别例从指定的文档中加载然后缓存并前往这个工具。相反的,imageWithContentsOfFile仅加载图片。下面的代码说了然这两种体例的用法:
那么我们应当若何挑选呢?如果你要加载一个年夜图片并且是一次性利用,那么就没需求缓存这个图片,用imageWithContentsOfFile足矣,如许不会浪费内存来缓存它。但是,在图片几次重用的环境下imageNamed是一个好很多的挑选。
25. 避免日期格局转换
如果你要用NSDateFormatter来措置很多日期格局,应当小心以待。就像先前提到的,任甚么时候候重用NSDateFormatters都是一个好的实际。但是,如果你需求更多速率,那么直接用C是一个好的计划。但是你信赖吗,我们另有更好的计划!如果你可以节制你所措置的日期格局,尽可能挑选Unix时候戳。你可以便利地从时候戳转换到NSDate:
如许会比用C来剖析日期字符串还快!需求重视的是,很多web API会以微秒的情势前往时候戳,因为这类格局在javascript中更便利利用。记着用dateFromUnixTimestamp之前除以1000就好了。
保举浏览:河南热线