25個(gè)增強(qiáng)iOS應(yīng)用程序性能的提示和技巧(高級(jí)篇)
在開發(fā)iOS應(yīng)用程序時(shí),讓程序具有良好的性能是非常關(guān)鍵的。這也是用戶所期望的,如果你的程序運(yùn)行遲鈍或緩慢,會(huì)招致用戶的差評(píng)。然而由于iOS 設(shè)備的局限性,有時(shí)候要想獲得良好的性能,是很困難的。在開發(fā)過程中,有許多事項(xiàng)需要記住,并且關(guān)于性能影響很容易就忘記。本文收集了25個(gè)關(guān)于可以提升 程序性能的提示和技巧。分為3個(gè)不同的等級(jí):初級(jí)、中級(jí)和高級(jí):
高級(jí)
當(dāng)且僅當(dāng)下面這些技巧能夠解決問題的時(shí)候,才使用它們:
22.加速啟動(dòng)時(shí)間
23.使用Autorelease Pool
24.緩存圖片 — 或者不緩存
25.盡量避免Date格式化
高級(jí)性能提升
尋找一些高明的方法,讓自己變?yōu)橐粋€(gè)全代碼忍者?下面這些高級(jí)的性能優(yōu)化技巧可以在適當(dāng)?shù)臅r(shí)候讓程序盡可能的高效運(yùn)行!
22) 加速啟動(dòng)時(shí)間
能快速的啟動(dòng)程序非常重要,特別是在用戶***次啟動(dòng)程序時(shí)。***映像對(duì)程序來(lái)說(shuō)非常重要!
讓程序盡量快速啟動(dòng)的方法就是盡量以異步方式執(zhí)行任務(wù),例如網(wǎng)絡(luò)請(qǐng)求,數(shù)據(jù)訪問或解析。
另外,避免使用臃腫的XIBs,因?yàn)閄IB的加載是在主線程中進(jìn)行的。但是記住storyboard沒有這樣的問題——所以如果可以的話就使用storyboard吧!
注意:在利用Xcode進(jìn)行調(diào)試時(shí),watchdog不會(huì)運(yùn)行,所在設(shè)備中測(cè)試程序啟動(dòng)性能時(shí),不要將設(shè)備連接到Xcode。
23) 使用Autorelease Pool
NSAutoreleasePool負(fù)責(zé)釋放一個(gè)代碼塊中的自動(dòng)釋放對(duì)象。一般都是由UIKit來(lái)創(chuàng)建的。不過有些情況下需要手動(dòng)創(chuàng)建NSAutoreleasePool。
例如,如果在代碼中創(chuàng)建了大量的臨時(shí)對(duì)象,你將注意到內(nèi)存使用量在增加,直到這些對(duì)象被釋放。問題是只有當(dāng)UIKit耗盡了 autorelease pool,這些對(duì)象才會(huì)被釋放,也就是說(shuō)當(dāng)不再需要這些對(duì)象之后,這些對(duì)象還在內(nèi)存中占據(jù)著資源。
不過這個(gè)問題完全可以避免:在@autoreleasepool代碼塊中創(chuàng)建臨時(shí)對(duì)象,如下代碼:
- NSArray *urls = <# An array of file URLs #>;
- for (NSURL *url in urls) {
- @autoreleasepool {
- NSError *error;
- NSString *fileContents = [NSString stringWithContentsOfURL:url
- encoding:NSUTF8StringEncoding error:&error];
- /* Process the string, creating and autoreleasing more objects. */
- }
- }
當(dāng)每次迭代完之后,都會(huì)釋放所有的autorelease對(duì)象。
關(guān)于NSAutoreleasePool的更多內(nèi)容可以閱讀蘋果的官方文檔。
24) 緩存圖片--或者不緩存
iOS中從程序bundle中加載UIImage一般有兩種方法。
***種比較常見:imageNamed。
第二種方法很少使用:imageWithContentsOfFile
為什么有兩種方法完成同樣的事情呢?imageNamed的優(yōu)點(diǎn)在于可以緩存已經(jīng)加載的圖片。蘋果的文檔中有如下說(shuō)法:
This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.
這種方法會(huì)在系統(tǒng)緩存中根據(jù)指定的名字尋找圖片,如果找到了就返回。如果沒有在緩存中找到圖片,該方法會(huì)從指定的文件中加載圖片數(shù)據(jù),并將其緩存起來(lái),然后再把結(jié)果返回。
而imageWithContentsOfFile方法只是簡(jiǎn)單的加載圖片,并不會(huì)將圖片緩存起來(lái)。這兩個(gè)方法的使用方法如下:
- UIImage *img = [UIImage imageNamed:@"myImage"]; // caching
- // or
- UIImage *img = [UIImage imageWithContentsOfFile:@"myImage"]; // no caching
那么該如何選擇呢?
如果加載一張很大的圖片,并且只使用一次,那么就不需要緩存這個(gè)圖片。這種情況imageWithContentsOfFile比較合適——系統(tǒng)不會(huì)浪費(fèi)內(nèi)存來(lái)緩存圖片。
然而,如果在程序中經(jīng)常需要重用的圖片,那么***是選擇imageNamed方法。這種方法可以節(jié)省出每次都從磁盤加載圖片的時(shí)間。
別走開,下頁(yè)繼續(xù)為您激情介紹
#p#
25) 盡量避免Date格式化
如果有許多日期需要使用NSDateFormatter,那么需要小心對(duì)待了。如之前(重用花銷很大的對(duì)象)所提到的,無(wú)論什么時(shí)候,都應(yīng)該盡量重用NSDateFormatters。
然而,如果你需要更快的速度,那么應(yīng)該使用C來(lái)直接解析日期,而不是NSDateFormatter。Sam Soffes寫了一篇文章,其中提供了一些解析ISO-8601格式日期字符的串代碼。你只需要簡(jiǎn)單的調(diào)整一下其中的代碼就可以滿足自己特殊的需求了。
這聽起來(lái)不錯(cuò)把——不過,你相信這還有更好的一個(gè)辦法嗎?
如果你自己能控制處理日期的格式,那么可以選擇 Unix timestamps(http://en.wikipedia.org/wiki/Unix_time)。Unix timestamps是一個(gè)簡(jiǎn)單的整數(shù),代表了從新紀(jì)元時(shí)間(epoch)開始到現(xiàn)在已經(jīng)過了多少秒,通常這個(gè)新紀(jì)元參考時(shí)間是00:00:00 UTC on 1 January 1970。
你可以很容易的見這個(gè)時(shí)間戳轉(zhuǎn)換為NSDate,如下所示:
- - (NSDate*)dateFromUnixTimestamp:(NSTimeInterval)timestamp {
- return [NSDate dateWithTimeIntervalSince1970:timestamp];
- }
上面這個(gè)方法比C函數(shù)還要快!
注意:許多網(wǎng)絡(luò)APIs返回的時(shí)間戳都是毫秒,因此需要注意的是在將這個(gè)時(shí)間戳傳遞給dateFromUnixTimestamp之前需要除以1000。
何去何從?
強(qiáng)烈建議對(duì)程序性能優(yōu)化感興趣的讀者看看下面列出來(lái)的WWDC視頻。在看視頻之前,你需要注冊(cè)一個(gè)Apple ID(注冊(cè)后就可以觀看所有WWDC2012的視頻):
#406: Adopting Automatic Reference Counting
#238: iOS App Performance: Graphics and Animations
#242: iOS App Performance: Memory
#235: iOS App Performance: Responsiveness
#409: Learning Instruments
#706: Networking Best Practices
#514: OpenGL ES Tools and Techniques
#506: Optimizing 2D Graphics and Animation Performance
#601: Optimizing Web Content in UIWebViews and Websites on iOS
#225: Up and Running: Making a Great Impression with Every Launch
下面這些視頻來(lái)自WWDC 2011 ,也非常有用:
#308: Blocks and Grand Central Dispatch in Practice
#323: Introducing Automatic Reference Counting
#312: iOS Performance and Power Optimization with Instruments
#105: Polishing Your App: Tips and tricks to improve the responsiveness and performance
#121: Understanding UIKit Rendering
這里還有更多相關(guān)視頻,大多數(shù)來(lái)自iOS 5技術(shù)講座:
Optimizing App Performance with Instruments
Understanding iOS View Compositing
基于 “Your iOS App Performance Hitlist” 視頻,Ole Begemann寫了一篇文章。蘋果還提供了一篇非常好的文章:性能優(yōu)化。其中提供的技巧和提示對(duì)程序性能提升很有幫助。