iOS關(guān)于性能優(yōu)化

在性能優(yōu)化中一個最具參考價值的屬性是FPS:Frames Per Second,其實就是屏幕刷新率,蘋果的iphone推薦的刷新率是60Hz,也就是說GPU每秒鐘刷新屏幕60次,這每刷新一次就是一幀frame,F(xiàn)PS也就是每秒鐘刷新多少幀畫面。靜止不變的頁面FPS值是0,這個值是沒有參考意義的,只有當(dāng)頁面在執(zhí)行動畫或者滑動的時候,F(xiàn)PS值才具有參考價值,F(xiàn)PS值的大小體現(xiàn)了頁面的流暢程度高低,當(dāng)?shù)陀?5的時候卡頓會比較明顯。

圖層混合:

每一個layer是一個紋理,所有的紋理都以某種方式堆疊在彼此的頂部。對于屏幕上的每一個像素,GPU需要算出怎么混合這些紋理來得到像素RGB的值。

當(dāng)Sa = 0.5時,RGB值為(0.5, 0, 0),可以看出,當(dāng)兩個不是完全不透明的CALayer覆蓋在一起時,GPU大量做這種復(fù)合操作,隨著這中操作的越多,GPU越忙碌,性能肯定會受到影響。

公式:

R = S + D * ( 1 – Sa )

結(jié)果的顏色是源色彩(頂端紋理)+目標(biāo)顏色(低一層的紋理)*(1-源顏色的透明度)。

當(dāng)Sa = 1時,R = S,GPU將不會做任何合成,而是簡單從這個層拷貝,不需要考慮它下方的任何東西(因為都被它遮擋住了),這節(jié)省了GPU相當(dāng)大的工作量。

一、入門級

1、用ARC管理內(nèi)存 2、在正確的地方使用 reuseIdentifier 3、盡量把views設(shè)置為透明 4、避免過于龐大的XIB 5、不要阻塞主線程

6、在ImageViews中調(diào)整圖片大小。如果要在UIImageView中顯示一個來自bundle的圖片,你應(yīng)保證圖片的大小和UIImageView的大小相同。在運行中縮放圖片是很耗費資源的,特別是UIImageView嵌套在UIScrollView中的情況下。如果圖片是從遠(yuǎn)端服務(wù)加載的你不能控制圖片大小,比如在下載前調(diào)整到合適大小的話,你可以在下載完成后,最好是用background thread,縮放一次,然后在UIImageView中使用縮放后的圖片。

7、選擇正確的Collection。

Arrays: 有序的一組值。使用index來lookup很快,使用value lookup很慢, 插入/刪除很慢。

Dictionaries: 存儲鍵值對。 用鍵來查找比較快。

Sets: 無序的一組值。用值來查找很快,插入/刪除很快。

8、打開gzip壓縮。app可能大量依賴于服務(wù)器資源,問題是我們的目標(biāo)是移動設(shè)備,因此你就不能指望網(wǎng)絡(luò)狀況有多好。減小文檔的一個方式就是在服務(wù)端和你的app中打開gzip。這對于文字這種能有更高壓縮率的數(shù)據(jù)來說會有更顯著的效用。 iOS已經(jīng)在NSURLConnection中默認(rèn)支持了gzip壓縮,當(dāng)然AFNetworking這些基于它的框架亦然。

二、中級

1、重用和延遲加載(lazy load) Views

更多的view意味著更多的渲染,也就是更多的CPU和內(nèi)存消耗,對于那種嵌套了很多view在UIScrollView里邊的app更是如此。

這里我們用到的技巧就是模仿UITableView和UICollectionView的操作: 不要一次創(chuàng)建所有的subview,而是當(dāng)需要時才創(chuàng)建,當(dāng)它們完成了使命,把他們放進一個可重用的隊列中。這樣的話你就只需要在滾動發(fā)生時創(chuàng)建你的views,避免了不劃算的內(nèi)存分配。

2、Cache, Cache, 還是Cache!

一個極好的原則就是,緩存所需要的,也就是那些不大可能改變但是需要經(jīng)常讀取的東西。

我們能緩存些什么呢?一些選項是,遠(yuǎn)端服務(wù)器的響應(yīng),圖片,甚至計算結(jié)果,比如UITableView的行高。

NSCache和NSDictionary類似,不同的是系統(tǒng)回收內(nèi)存的時候它會自動刪掉它的內(nèi)容。

3、權(quán)衡渲染方法.性能能還是要bundle保持合適的大小。

4、處理內(nèi)存警告.移除對緩存,圖片object和其他一些可以重創(chuàng)建的objects的strong references.

5、重用大開銷對象

6、一些objects的初始化很慢,比如NSDateFormatter和NSCalendar。然而,你又不可避免地需要使用它們,比如從JSON或者XML中解析數(shù)據(jù)。想要避免使用這個對象的瓶頸你就需要重用他們,可以通過添加屬性到你的class里或者創(chuàng)建靜態(tài)變量來實現(xiàn)。

7、避免反復(fù)處理數(shù)據(jù).在服務(wù)器端和客戶端使用相同的數(shù)據(jù)結(jié)構(gòu)很重要。

8、選擇正確的數(shù)據(jù)格式.解析JSON會比XML更快一些,JSON也通常更小更便于傳輸。從iOS5起有了官方內(nèi)建的JSON deserialization 就更加方便使用了。但是XML也有XML的好處,比如使用SAX 來解析XML就像解析本地文件一樣,你不需像解析json一樣等到整個文檔下載完成才開始解析。當(dāng)你處理很大的數(shù)據(jù)的時候就會極大地減低內(nèi)存消耗和增加性能。

9、正確設(shè)定背景圖片

全屏背景圖,在view中添加一個UIImageView作為一個子View

只是某個小的view的背景圖,你就需要用UIColor的colorWithPatternImage來做了,它會更快地渲染也不會花費很多內(nèi)存:

10、減少使用Web特性。想要更高的性能你就要調(diào)整下你的HTML了。第一件要做的事就是盡可能移除不必要的javascript,避免使用過大的框架。能只用原生js就更好了。盡可能異步加載例如用戶行為統(tǒng)計script這種不影響頁面表達的javascript。注意你使用的圖片,保證圖片的符合你使用的大小。

11、Shadow Path 。CoreAnimation不得不先在后臺得出你的圖形并加好陰影然后才渲染,這開銷是很大的。使用shadowPath的話就避免了這個問題。使用shadow path的話iOS就不必每次都計算如何渲染,它使用一個預(yù)先計算好的路徑。但問題是自己計算path的話可能在某些View中比較困難,且每當(dāng)view的frame變化的時候你都需要去update shadow path.

12、優(yōu)化Table View

正確使用reuseIdentifier來重用cells

盡量使所有的view opaque,包括cell自身

避免漸變,圖片縮放,后臺選人

緩存行高

如果cell內(nèi)現(xiàn)實的內(nèi)容來自web,使用異步加載,緩存請求結(jié)果

使用shadowPath來畫陰影

減少subviews的數(shù)量

盡量不適用cellForRowAtIndexPath:,如果你需要用到它,只用-一次然后緩存結(jié)果

使用正確的數(shù)據(jù)結(jié)構(gòu)來存儲數(shù)據(jù)

使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight來設(shè)定固定的高,不要請求delegate

13、選擇正確的數(shù)據(jù)存儲選項

NSUserDefaults的問題是什么?雖然它很nice也很便捷,但是它只適用于小數(shù)據(jù),比如一些簡單的布爾型的設(shè)置選項,再大點你就要考慮其它方式了

XML這種結(jié)構(gòu)化檔案呢?總體來說,你需要讀取整個文件到內(nèi)存里去解析,這樣是很不經(jīng)濟的。使用SAX又是一個很麻煩的事情。

NSCoding?不幸的是,它也需要讀寫文件,所以也有以上問題。

在這種應(yīng)用場景下,使用SQLite 或者 Core Data比較好。使用這些技術(shù)你用特定的查詢語句就能只加載你需要的對象。

在性能層面來講,SQLite和Core Data是很相似的。他們的不同在于具體使用方法。

Core Data代表一個對象的graph model,但SQLite就是一個DBMS。

Apple在一般情況下建議使用Core Data,但是如果你有理由不使用它,那么就去使用更加底層的SQLite吧。

如果你使用SQLite,你可以用FMDB這個庫來簡化SQLite的操作,這樣你就不用花很多經(jīng)歷了解SQLite的C API了。

三、高級

1、加速啟動時間。快速打開app是很重要的,特別是用戶第一次打開它時,對app來講,第一印象太太太重要了。你能做的就是使它盡可能做更多的異步任務(wù),比如加載遠(yuǎn)端或者數(shù)據(jù)庫數(shù)據(jù),解析數(shù)據(jù)。避免過于龐大的XIB,因為他們是在主線程上加載的。所以盡量使用沒有這個問題的Storyboards吧!一定要把設(shè)備從Xcode斷開來測試啟動速度

2、使用Autorelease Pool。NSAutoreleasePool`負(fù)責(zé)釋放block中的autoreleased objects。一般情況下它會自動被UIKit調(diào)用。但是有些狀況下你也需要手動去創(chuàng)建它。假如你創(chuàng)建很多臨時對象,你會發(fā)現(xiàn)內(nèi)存一直在減少直到這些對象被release的時候。這是因為只有當(dāng)UIKit用光了autorelease pool的時候memory才會被釋放。消息是你可以在你自己的@autoreleasepool里創(chuàng)建臨時的對象來避免這個行為。

3、選擇是否緩存圖片。常見的從bundle中加載圖片的方式有兩種,一個是用imageNamed,二是用imageWithContentsOfFile,第一種比較常見一點。

4、避免日期格式轉(zhuǎn)換。如果你要用NSDateFormatter來處理很多日期格式,應(yīng)該小心以待。就像先前提到的,任何時候重用NSDateFormatters都是一個好的實踐。如果你可以控制你所處理的日期格式,盡量選擇Unix時間戳。你可以方便地從時間戳轉(zhuǎn)換到NSDate:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在性能優(yōu)化中一個最具參考價值的屬性是FPS:Frames Per Second,其實就是屏幕刷新率,蘋果的ipho...
    iOS猿_員閱讀 1,182評論 1 3
  • 在性能優(yōu)化中一個最具參考價值的屬性是FPS:Frames Per Second,其實就是屏幕刷新率,蘋果的ipho...
    隔墻送來秋千影閱讀 862評論 0 3
  • instruments 在iOS上進行性能分析的時候,首先考慮借助instruments這個利器分析出問題出在哪,...
    evanleeeee閱讀 1,231評論 0 51
  • 今天放學(xué)的路上,媽媽跟我說:要告訴我一個好消息,是嬸嬸生了一個小弟弟。我聽了這個好消息,實在太高興啦,就問媽...
    張栩華閱讀 273評論 0 0
  • 今天是星期五,和往常一樣五點四十就起來給孩子做飯。做上飯燒水,聽見校車來拉初中的學(xué)生就趕集叫孩子起來吃飯。今天還行...
    張梓暄媽媽閱讀 262評論 0 0

友情鏈接更多精彩內(nèi)容