初級html
在開發過程當中,下面這些初級技巧須要時刻注意:ios
1.使用ARC進行內存管理
2.在適當的狀況下使用reuseIdentifier
3.儘量將View設置爲不透明(Opaque)
4.避免臃腫的XIBs
5.不要阻塞主線程git
6.讓圖片的大小跟UIImageView同樣
7.選擇正確的集合
8.使用GZIP壓縮github
1) 使用ARC進行內存管理web
ARC是在iOS 5中發佈的,它解決了最多見的內存泄露問題——也是開發者最容易健忘的。ARC的全稱是「Automatic Reference Counting」——自動引用計數,它會自動的在代碼中作retain/release工做,開發者不用再手動處理。數據庫
下面是建立一個View通用的一些代碼塊:編程
在上面代碼結束的地方很容易會忘記調用release。不過當使用ARC時,ARC會在後臺自動的幫你調用release。json
ARC除了能避免內存泄露外,還有助於程序性能的提高:當程序中的對象再也不須要的時候,ARC會自動銷燬對象。因此,你應該在工程中使用ARC。數組
下面是學習ARC的一些資源:緩存
Tony Dahbura的如何在Cocos2D 2.X工程中使用ARC
若是你仍然不肯定ARC帶來的好處,那麼看一些這篇文章:8個關於ARC的神話——這可以讓你相信你應該在工程中使用ARC!
值得注意的是,ARC並不能避免全部的內存泄露。使用ARC以後,工程中可能還會有內存泄露,不過引發這些內存泄露的主要緣由是:block,retain循環,對CoreFoundation對象(一般是C結構)管理不善,以及真的是代碼沒寫好。
這裏有一篇文章是介紹哪些問題是ARC不能解決的 — 以及如何處理這些問題。
2) 在適當的狀況下使用reuseIdentifier
爲了得到最佳性能,當在tableView:cellForRowAtIndexPath:方法中返回cell時,table view的數據源通常會重用UITableViewCell對象。table view維護着UITableViewCell對象的一個隊列或者列表,這些數據源已經被標記爲重用了。
若是沒有使用reuseIdentifier會發生什麼?若是你在程序中沒有使用reuseIdentifier,table view每次顯示一個row時,都會配置一個全新的cell。這實際上是一個很是消耗資源的操做,而且會影響程序中table view滾動的效率。
自iOS 6以來,你可能還但願header和footer views,以及UICollectionView的cell和supplementary views。
爲了使用reuseIdentifiers,在table view請求一個新的cell時,在數據源中調用下面的方法:
若是table view維護的UITableViewCell隊列或列表中有可用的cell,則從隊列從移除一個已經存在的cell,若是沒有的話,就從以前註冊的nib文件或類中建立一個新的cell。若是沒有能夠重用的cell,而且沒有註冊nib文件或類,tableview的dequeueReusableCellWithIdentifier:方法會返回一個nil。
3) 儘量將View設置爲不透明(Opaque)
若是view是不透明的,那麼應該將其opaque屬性設置爲YES。爲何要這樣作呢?這樣設置可讓系統以最優的方式來繪製view。opaque屬性能夠在Interface Builder或代碼中設置。
蘋果的官方文檔對opaque屬性有以下解釋:
This property provides a hint to the drawing system as to how it should treat the view. If set to YES, the drawing system treats the view as fully opaque, which allows the drawing system to optimize some drawing operations and improve performance. If set to NO, the drawing system composites the view normally with other content. The default value of this property is YES.
(opaque屬性提示繪製系統如何處理view。若是opaque設置爲YES,繪圖系統會將view看爲徹底不透明,這樣繪圖系統就能夠優化一些繪製操做以提高性能。若是設置爲NO,那麼繪圖系統結合其它內容來處理view。默認狀況下,這個屬性是YES。)
若是屏幕是靜止的,那麼這個opaque屬性的設置與否不是一個大問題。可是,若是view是嵌入到scroll view中的,或者是複雜動畫的一部分,不將設置這個屬性的話確定會影響程序的性能!能夠經過模擬器的Debug\Color Blended Layers選項來查看哪些view沒有設置爲不透明。爲了程序的性能,儘量的將view設置爲不透明!
4) 避免臃腫的XIBs
在iOS 5中開始使用Storyboards,而且將替代XIBs。不過在有些狀況下XIBs仍然有用。若是你的程序須要運行在裝有iOS 5以前版本的設備上,或者要自定義可重用的view,那麼是避免不了要使用XIBs的。
若是必需要使用XIBs的話,儘可能讓XIBs文件簡單。而且每一個view controller對於一個XIB文件,若是能夠的話,把一個view controller的view不一樣的層次單獨分到一個XIBs文件中。
(注意:當把一個XIB文件加載到內存時,XIB文件中的全部內容都將被加載到內存中,包括圖片。若是有一個view還不當即使用的話,就會形成內存的浪費。而這在storyboard中是不會發生的,由於storyboard還在須要的時候才實例化一個view controller。)
當加載XIB時,全部涉及到的圖片都將被緩存,而且若是是開發的程序是針對OS X的話,聲音文件也會被加載。蘋果的官方文檔這樣說:
When you load a nib file that contains references to image or sound resources, the nib-loading code reads the actual image or sound file into memory and and caches it. In OS X, image and sound resources are stored in named caches so that you can access them later if needed. In iOS, only image resources are stored in named caches. To access images, you use the imageNamed: method of NSImage or UIImage, depending on your platform.
(當加載一個nib文件時,也會將nib文件涉及到的圖片或聲音資源加載到內存中,nib-loading代碼會將實際的圖片或聲音文件讀取到內存中,並一直緩存着。在OS X中,圖片和聲音資源都存儲在命名緩存中,這樣以後若是須要的話,能夠對其進行訪問。在iOS中,只有圖片資源被存儲到命名緩存中。要訪問圖片的話,使用NSImage或UIImage(根據不一樣的系統)的imageNamed:方法便可。)
顯然,在使用storyboard時也會發生相似的緩存操做;不過我沒有找到相關內容的任何資料。想要學習storyboard的更多知識嗎?能夠看看Matthijs Hollemans寫的iOS 5中:初級Storyboard Part 1和Part2。
5) 不要阻塞主線程
在主線程作全部任務的風險是:若是你的代碼阻塞了主線程,那麼程序將出現反應遲鈍。這回招致用戶在App Store上對程序的差評!
在執行I/O操做中,大多數狀況下都會祖塞主線程,這些操做須要從讀寫外部資源,例如磁盤或者網絡。
關於網絡操做可使用NSURLConnection的以下方法,以異步的方式來執行:
或者使用第三方框架,例如AFNetworking。
若是你須要作一些其它類型開銷很大的操做(例如執行一個時間密集型的計算或者對磁盤進行讀寫),那麼就使用GCD(Grand Central Dispatch),或NSOperations 和 NSOperationQueues。
下面的代碼是使用GCD的一個模板:
如上代碼,爲何在第一個dispatch_async裏面還嵌套了一個dispatch_async呢?這是由於關於UIKit相關的代碼須要在主線程裏面執行。
能夠看看Ray Wenderlich中的教程:iOS中多線程和GCD—初級,以及Soheil Azarpour的如何使用NSOperations和NSOperationQueues教程。
6) 讓圖片的大小跟UIImageView同樣
若是是從遠程服務中下載圖片,有時候你控制不了圖片的尺寸,或者在下載以前沒法在服務器上進行圖片的縮放。這種狀況,當圖片下載完以後,你能夠手動進行圖片的縮放——作好是在後臺線程中!——而後再在UIImageView中使用縮放過的圖片。
7) 選擇正確的集合
8) 使用GZIP壓縮
愈來愈多的程序依賴於外部數據,這些數據通常來自遠程服務器或者其它的外部APIs。有時候你須要開發一個程序來下載一些數據,這些數據能夠是XML,JSON,HTML或者其它一些文本格式。
問題是在移動設備上的網絡是不肯定的。用戶的設備可能在EDGE網絡一分鐘,而後接着又在3G網絡中。無論在什麼狀況下,都不要讓用戶等待。
有一個能夠優化的選擇:使用GZIP對網絡傳輸中的數據進行壓縮,這樣能夠減少文件的大小,並加快下載的速度。壓縮對於文本數據特別有用,由於文本具備很高的壓縮比。
iOS中,若是使用NSURLConnection,那麼默認狀況下已經支持GZIP壓縮了,而且基於NSURLConnection的框架頁支持GZIP壓縮,如AFNetworking。甚至有些雲服務提供商已經提供發送經壓縮過的響應內容,例如Google App Engine。
這裏有一篇關於GZIP壓縮很好的文章,介紹瞭如何在Apache活IIS服務器中開啓支持GZIP壓縮。
在性能優化時,當你碰到一些複雜的問題,應該注意和使用以下技巧:
9.重用和延遲加載View
10.緩存、緩存、緩存
11.考慮繪製
12.處理內存警告
13.重用花銷很大的對象
14.使用Sprite Sheets
15.避免從新處理數據
16.選擇正確的數據格式
17.設置適當的背景圖片
18.下降Web內容的影響
19.設置陰影路徑
20.優化TableView
21.選擇正確的數據存儲方式
中級性能提高
如今,在進行代碼優化時,你已經可以完成一些初級性能優化了。可是下面還有另一些優化方案,雖然可能不太明顯(取決於程序的架構和相關代碼),可是,若是可以正確的利用好這些方案,那麼它們對性能的優化將很是明顯!
9) 重用和延遲加載View
程序界面中包含更多的view,意味着界面在顯示的時候,須要進行更多的繪製任務;也就意味着須要消耗更多的CPU和內存資源。特別是在一個UIScrollView裏面加入了許多view。
這種狀況的管理技巧能夠參考UITableView和UICollectionView的行爲:不要一次性建立全部的subview,而是在須要的時候在建立view,而且當view使用完畢時候將它們添加到重用隊列中。
這樣就能夠僅在UIScrollView滾動的時候才配置view,以此能夠避免分配建立view的帶來的成本——這多是很是耗資源的。
如今有這樣的一個問題:在程序中須要顯示的view在什麼時機建立(好比說,當用戶點擊某個按鈕,須要顯示某個view)。這裏有兩種可選方法:
在屏幕第一次加載以及隱藏的時候,建立view;而後在須要的時候,再把view顯示出來。
直到須要顯示view的時候,才建立並顯示view。
每種方法都有各自的優勢和缺點。第一種方法須要消耗更多的內容,由於建立出來的view一直佔據着內存,直到view被release掉。不過,使用這種方法,當用戶點擊按鈕時,程序會很快的顯示出view,由於只須要修改一下view的可見性便可。而第二種方法則產生相反的效果;當須要的時候猜建立view,這會消耗更少的內存;不過,當用戶點擊按鈕的時候,不會當即顯示出view。
10) 緩存、緩存、緩存
在開發程序時,一個重要的規則就是「緩存重要的內容」——這些內容通常不會改變,而且訪問的頻率比較高。
能夠緩存寫什麼內容呢?好比遠程服務器的響應內容,圖片,甚至是計算結果,好比UITableView的行高。
NSURLConnection根據HTTP頭的處理過程,已經把一些資源緩存到磁盤和內存中了。你甚至能夠手動建立一個NSURLRequest ,讓其只加載緩存的值。
下面的代碼片斷通常用在爲圖片建立一個NSURLRequest:
注意:你可使用NSURLConnection抓取一個URL請求,可是一樣可使用AFNetworking來抓取,這種方法不用修改全部網絡相關的代碼——這是一個技巧!
更多關於HTTP 緩存, NSURLCache, NSURLConnection 以及相關的內容, 那麼看一下NSHipster中的the NSURLCache entry。
若是你須要緩存的內容沒涉及到HTTP請求,那使用NSCache。NSCache的外觀和行爲與NSDictionary相似, 可是,當系統須要回收內存時,NSCache會自動的裏面存儲的內容。Mattt Thompson 在NSHipster上寫了一篇關於NSCache很是不錯的文章。
更多關於HTTP緩存的內容,建議讀一下Google的這篇文章:best-practices document on HTTP caching。
11) 考慮繪製
這些方法的複雜程度不一樣,性能也有區別。這篇關於iOS中圖形性能的文章值得一讀。其中Andy Matuschak(曾經是蘋果的UIKit小組的組員)對這篇文章的評論中,對於不一樣的方法及其性能權衡有很是好的一個看法。
簡單來講,使用預渲染圖片技術是最快的,由於iOS中不用等到在屏幕上顯示的時候才建立圖形和對形狀進行繪製(圖片已經建立好了!)。這樣帶來的問題是須要把全部的圖片都放到程序bundle中,從而增長了程序的大小。所以使用可伸縮圖片在這裏將排上用場了:能夠移除「浪費」空間的圖片——iOS能夠重複利用。而且針對不一樣的元素(例如按鈕)不須要建立不一樣的圖片。
不過,使用圖片的話會失去代碼對圖片的控制能力,進而針對不一樣的程序,就須要重複的生成每個須要的圖片,並反覆的放到每一個程序中。這個處理過程通常會比較慢。另一點就是若是你須要一個動畫,或者許多圖片都要進行輕微的調整(好比多個顏色的覆蓋),那麼須要在程序中加入許多圖片,進而增長了程序bundle的大小。
總的來講,要考慮一下什麼纔是最重要的:繪製性能仍是程序大小。通常來講都重要,因此在同一個工程中,應該兩種都應考慮。
12) 處理內存警告
當系統內存偏低時,iOS會通知全部在運行的程序。蘋果的官方文檔中介紹瞭如何處理低內存警告:
If your app receives this warning, it must free up as much memory as possible. The best way to do this is to remove strong references to caches, image objects, and other data objects that can be recreated later.
若是程序收到了低內存警告,在程序中必須儘可能釋放內存。最佳方法就是移除強引用的涉及到的緩存,圖片對象,以及其它能夠在以後使用時還能夠從新建立的數據對象。
UIKit中提供了以下幾種方法來接收低內存(low-memory)警告:
實現app delegate中的applicationDidReceiveMemoryWarning: 方法。
在UIViewController子類中重寫(Override)didReceiveMemoryWarning方法。
在通知中內心面註冊UIApplicationDidReceiveMemoryWarningNotificatio通知。
在收到以上任意的警告時,須要當即釋聽任何不須要的內存。
例如,UIViewController的默認狀況是清除掉當前不可見的view;在UIViewController的子類中,能夠清除一些額外的數據。程序中不沒有顯示在當前屏幕中的圖片也能夠release掉。
當收到低內存警告時,儘可能釋放內存是很是重要的。不然,運行中的程序有可能會被系統殺掉。
不過,在清除內存時要注意一下:確保被清除的對象以後還能夠被建立出來。另外,在開發程序的時候,請使用iOS模擬器中的模擬內存警告功能對程序進行測試!
13) 重用花銷很大的對象
當使用這些對象時,爲了不性能上的瓶頸,能夠嘗試儘可能重用這些對象——在類中添加一個屬性或者建立一個靜態變量。
注意,若是使用靜態變量的話,對象會在程序運行的時候一直存在,就像單例同樣。
下面的代碼演示建立一個延遲加載的日期格式屬性。第一次調用屬性的時候,會建立一個新的日期格式。以後再調用的話,會返回已經建立好的實例對象:
另外,還須要記住的是在設置NSDateFormatter的日期格式時,一樣跟建立新的一個NSDateFormatter實例對象時同樣慢!所以,在程序中若是須要頻繁的處理日期格式,那麼對NSDateFormatter進行重用是很是好的。
14) 使用Sprite Sheets
下面是兩個很是不錯的sprite sheets教程:
如何在Cocos2D中使用紋理包(Texture Packer)和像素格式來建立並優化Sprite Sheets 。(第二個教程詳細的介紹了像素格式——在遊戲中能夠衡量性能的影響)
若是還不熟悉sprite sheets,能夠看看這裏的介紹:SpriteSheets – 視頻, Part 1和 Part 2 。這兩個視頻的做者是Andreas Löw, 他是紋理包(Texture Packer)的建立者, 紋理包是建立sprite sheets的重要工具。
除了使用sprite sheets外,這裏還介紹了一些用於遊戲開發中的技巧,例如,若是你有不少sprite(好比射擊類遊戲中),那麼能夠重用sprite,而不用每次都建立sprite。
15) 避免從新處理數據
許多程序都須要從遠程服務器中獲取數據,以知足程序的需求。這些數據通常是JSON或XML格式。在請求和接收數據時,使用相同的數據結構很是重要。
爲何呢?在內存中把數據轉換爲適合程序的數據格式是須要付出額外代價的。
例如,若是你須要在table view中顯示一些數據,那麼請求和接收的數據格式最好是數組格式的,這樣能夠避免一些中間操做——將數據轉換爲適合程序使用的數據結構。
相似的,若是程序是根據鍵來訪問具體的值,那麼最好請求和接收一個鍵/值對字典。
在第一時間得到的數據就是所須要格式的,能夠避免將數據轉換爲適合程序的數據格式帶來的額外代價。
16) 選擇正確的數據格式
將數據從程序傳到網絡服務器中有多種方法,其中使用的數據格式基本都是JSON和XML。你須要作的就是在程序中選擇正確的數據格式。
JSON的解析速度很是快,而且要比XML小得多,也就意味着只須要傳輸更少數據。而且在iOS5以後,已經有內置的JSON反序列化API了,因此使用JSON是很容易的。
不過XML也有它本身的優點:若是使用SAX方法來解析XML,那麼能夠邊讀XML邊解析,並不用等到所有的XML獲取到了纔開始解析,這與JSON是不一樣的。當處理大量數據時,這種方法能夠提高性能並減小內存的消耗。
17) 設置適當的背景圖片
在iOS編碼中,跟別的許多東西相似,這裏也有兩種方法來給view設置一個背景圖片:
1.可使用UIColor的colorWithPatternImge方法來建立一個顏色,並將這個顏色設置爲view的背景顏色。
2.能夠給view添加一個UIImageView子視圖。
若是你有一個全尺寸的背景圖片,那麼應該使用UIImageView,由於UIColor的colorWithPatternImge方法是用來建立小圖片的——該圖片會被重複使用。此時使用UIImageView會節省不少內存。
不過,若是你計劃用小圖片當作背景,那麼應該使用UIColor的colorWithPatternImge方法。這種狀況下繪製速度會很快,而且不會消耗大量的內存。
18) 下降Web內容的影響
UIWebView很是有用。用它能夠很容易的顯示web內容,甚至能夠構建UIKit空間難以顯示的內容。
不過,你能夠能已經注意到程序中使用的UIWebView組建沒有蘋果的Safari程序快。這是由於JIT編譯限制了WebKit的Nitro引擎的使用。
所以爲了得到更加的性能,須要調整一下HTML的大小。首先就是儘可能的擺脫JavaScript,並避免使用大的礦建,例如jQuery。有時候使用原始的JavaScript要比別的框架快。
另外,儘可能的異步加載JavaScript文件——特別是不直接影響到頁面行爲時,例如分析腳本。
最後——讓使用到的圖片,跟實際須要的同樣大小。如以前提到的,儘可能使用sprite sheets,以此節省內存和提高速度。
更多相關信息,能夠看一下: WWDC 2012 session #601 – 在iOS中優化UIWebView和網站中的Web內容。
19) 設置陰影路徑
若是須要在view活layer中添加一個陰影,該如何處理呢?大多數開發者首先將QuartzCore框架添加到工程中,而後添加以下代碼:
上面這種方法有一個問題,Core Animation在渲染陰影效果以前,必須經過作一個離屏(offscreen)才能肯定view的形狀,而這個離屏操做很是耗費資源。下面方法能夠更容易地讓系統進行陰影渲染:設置陰影路徑!
經過設置陰影路徑,iOS就不用老是再計算該如何繪製陰影了。只須要使用你預先計算好的路徑便可。有一點很差的是,根據view的格式,本身可能很難計算出路徑。另一個問題就是當view的frame改變時,必須每次都更新一下陰影路徑。
若是你想了解更多相關信息,可參看Mark Pospesel的一篇文章:shadowPath。
20) 優化TableView
Table views須要快速的滾動——若是不能的話,用戶會感受到停頓。爲了讓table view平滑的滾動,確保遵循了以下建議:
1.設置正確的reuseIdentifer以重用cell。
2.儘可能將view設置爲不透明,包括cell自己。
3.避免漸變,圖像縮放以及離屏繪製。
4.若是row的高度不相同,那麼將其緩存下來。
5.若是cell顯示的內容來此網絡,那麼確保這些內容是經過異步來獲取的。
6.使用shadowPath來設置陰影。
7.減小subview的數量。
8.在cellForRowAtIndexPath:中儘可能作更少的操做。若是須要作一些處理,那麼最好作過一次以後,就將結果緩存起來。
9.使用適當的數據結構來保存須要的信息。不一樣的結構會帶來不一樣的操做代價。
10.使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight 來設置一個恆定 高度,而不要從delegate中獲取。
21) 選擇正確的數據存儲方式
當須要存儲和讀取大量的數據時,該如何選擇存儲方式呢?有以下選擇:
1.使用NSUserDefaults進行存儲
2.保存爲XML,JSON或Plist格式的文件
3.利用NSCoding進行歸檔
4.存儲到一個本地數據庫,例如SQLite。
5.使用Core Data.
使用NSUserDefaults有什麼問題呢? 雖然NSUserDefaults很好而且容易,不過只只針對於存儲小量數據(好比你的級別,或者聲音是開或關)。若是要存儲大量的數據,最好選擇別的存儲方式。
大量數據保存爲結構化的文件也可能會帶來問題。通常,在解析這些結構數據以前,須要將內容所有加載到內存中,這是很消耗資源的。雖然可使用SAX來處理XML文件,可是這有點複雜。另外,加載到內存中的全部對象,不必定所有都須要用到。
那麼使用NSCoding來保存大量數據怎麼樣呢?由於它一樣是對文件進行讀寫,所以依然存在上面說的問題。
要保存大量的數據,最好使用SQLite或Core Data。經過SQLite或Core Data能夠進行具體的查詢——只須要獲取並加載須要的數據對象——避免對數據進行不合理的搜索。在性能方面,SQLite和Core Data差不大。
SQLite和Core Data最大的區別實際上就是用法上。Core Data表明一個對象模型,而SQLite只是一個DBMS。通常,蘋果建議使用Core Data,不過若是你有特殊的緣由不能使用Core Data的話,可使用低級別的SQLite。
在程序中,若是選擇使用SQLite,這裏有個方便的庫FMDB :能夠利用該庫操做SQLite數據庫,而不用深刻使用SQLite C API。
高級
當且僅當下面這些技巧可以解決問題的時候,才使用它們:
22.加速啓動時間
23.使用Autorelease Pool
24.緩存圖片 — 或者不緩存
25.儘可能避免Date格式化
高級性能提高
尋找一些高明的方法,讓本身變爲一個全代碼忍者?下面這些高級的性能優化技巧能夠在適當的時候讓程序儘量的高效運行!
22) 加速啓動時間
能快速的啓動程序很是重要,特別是在用戶第一次啓動程序時。第一映像對程序來講很是重要!
讓程序儘可能快速啓動的方法就是儘可能以異步方式執行任務,例如網絡請求,數據訪問或解析。
另外,避免使用臃腫的XIBs,由於XIB的加載是在主線程中進行的。可是記住storyboard沒有這樣的問題——因此若是能夠的話就使用storyboard吧!
注意:在利用Xcode進行調試時,watchdog不會運行,所在設備中測試程序啓動性能時,不要將設備鏈接到Xcode。
23) 使用Autorelease Pool
NSAutoreleasePool負責釋放一個代碼塊中的自動釋放對象。通常都是由UIKit來建立的。不過有些狀況下須要手動建立NSAutoreleasePool。
例如,若是在代碼中建立了大量的臨時對象,你將注意到內存使用量在增長,直到這些對象被釋放。問題是隻有當UIKit耗盡了 autorelease pool,這些對象纔會被釋放,也就是說當再也不須要這些對象以後,這些對象還在內存中佔據着資源。
不過這個問題徹底能夠避免:在@autoreleasepool代碼塊中建立臨時對象,以下代碼:
當每次迭代完以後,都會釋放全部的autorelease對象。
關於NSAutoreleasePool的更多內容能夠閱讀蘋果的官方文檔。
24) 緩存圖片--或者不緩存
iOS中從程序bundle中加載UIImage通常有兩種方法。
第一種比較常見:imageNamed。
第二種方法不多使用:imageWithContentsOfFile
爲何有兩種方法完成一樣的事情呢?imageNamed的優勢在於能夠緩存已經加載的圖片。蘋果的文檔中有以下說法:
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.
這種方法會在系統緩存中根據指定的名字尋找圖片,若是找到了就返回。若是沒有在緩存中找到圖片,該方法會從指定的文件中加載圖片數據,並將其緩存起來,而後再把結果返回。
而imageWithContentsOfFile方法只是簡單的加載圖片,並不會將圖片緩存起來。這兩個方法的使用方法以下:
那麼該如何選擇呢?
若是加載一張很大的圖片,而且只使用一次,那麼就不須要緩存這個圖片。這種狀況imageWithContentsOfFile比較合適——系統不會浪費內存來緩存圖片。
然而,若是在程序中常常須要重用的圖片,那麼最好是選擇imageNamed方法。這種方法能夠節省出每次都從磁盤加載圖片的時間。
25) 儘可能避免Date格式化
若是有許多日期須要使用NSDateFormatter,那麼須要當心對待了。如以前(重用花銷很大的對象)所提到的,不管何時,都應該儘可能重用NSDateFormatters。
然而,若是你須要更快的速度,那麼應該使用C來直接解析日期,而不是NSDateFormatter。Sam Soffes寫了一篇文章,其中提供了一些解析ISO-8601格式日期字符的串代碼。你只須要簡單的調整一下其中的代碼就能夠知足本身特殊的需求了。
這聽起來不錯把——不過,你相信這還有更好的一個辦法嗎?
若是你本身能控制處理日期的格式,那麼能夠選擇 Unix timestamps(http://en.wikipedia.org/wiki/Unix_time)。Unix timestamps是一個簡單的整數,表明了重新紀元時間(epoch)開始到如今已通過了多少秒,一般這個新紀元參考時間是00:00:00 UTC on 1 January 1970。
你能夠很容易的見這個時間戳轉換爲NSDate,以下所示:
上面這個方法比C函數還要快!
注意:許多網絡APIs返回的時間戳都是毫秒,所以須要注意的是在將這個時間戳傳遞給dateFromUnixTimestamp以前須要除以1000。
何去何從?
強烈建議對程序性能優化感興趣的讀者看看下面列出來的WWDC視頻。在看視頻以前,你須要註冊一個Apple ID(註冊後就能夠觀看全部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
下面這些視頻來自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