iOS性能優(yōu)化

首先,開發(fā)過程中,遇到過的內(nèi)存的問題

1、self被delegate強(qiáng)引用了,導(dǎo)致內(nèi)存不被釋放。

2、imageNamed讀取圖片的方法,會(huì)緩存在內(nèi)存中,所以較大的圖片,還是用imageWithContentsOfFile。

3、block里沒有使用弱引用self,導(dǎo)致一直持有self得不到釋放。

一、內(nèi)存優(yōu)化

1、多使用懶加載:不要一次創(chuàng)建所有的subview,而是當(dāng)需要時(shí)才創(chuàng)建,當(dāng)它們完成了使命,把他們放進(jìn)一個(gè)可重用的隊(duì)列中,避免了不劃算的內(nèi)存分配。

2、使用復(fù)用:內(nèi)存上對(duì)對(duì)象的復(fù)用,UITableView就是例子。另外,一些objects的初始化很慢,比如NSDateFormatter和NSCalendar,想要避免使用這個(gè)對(duì)象的瓶頸就需要重用他們,可以通過添加屬性到你的class里或者創(chuàng)建靜態(tài)變量來實(shí)現(xiàn)。

3、使用xib和storyboard布局注意簡潔化:因?yàn)榧虞d一個(gè)xib的時(shí)候所有內(nèi)容都被放在了內(nèi)存里,包括任何圖片。嘗試為每個(gè)Controller配置一個(gè)單獨(dú)的xib,盡可能把一個(gè)View Controller的view層次結(jié)構(gòu)分散到單獨(dú)的xib中去。如果有一個(gè)不會(huì)即刻用到的view,你這就是在浪費(fèi)寶貴的內(nèi)存資源了。StoryBoard中不允許有單個(gè)view的存在,因此很多時(shí)候我們需要借助于單個(gè)的xib來自定義UI。

4、選擇正確的數(shù)據(jù)結(jié)構(gòu):精心選擇的數(shù)據(jù)結(jié)構(gòu)可以帶來更高的運(yùn)行或者存儲(chǔ)效率。

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

Dictionaries: 存儲(chǔ)鍵值對(duì),用鍵來查找比較快。

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

5、由于后臺(tái)運(yùn)行的原因,導(dǎo)致的寫代碼時(shí)要注意的:由于在后臺(tái)時(shí),為了減少程序占用的內(nèi)存,系統(tǒng)會(huì)自動(dòng)在回收一些系統(tǒng)幫助你開辟的內(nèi)存。

所以:

a.盡量減少內(nèi)存的使用。當(dāng)內(nèi)存不足時(shí),iOS將kill那些消耗內(nèi)存最多的 App。

b.釋放所有的共享資源,比如 Calendar 與 Address book。當(dāng)應(yīng)用程序進(jìn)入后臺(tái)時(shí),如果它還在使用或沒有釋放共享資源,iOS會(huì)立即kill掉該應(yīng)用程序。

c.對(duì)于圖片對(duì)象、可以重新加載的大的視頻或數(shù)據(jù)文件和任何沒用而且可以輕易創(chuàng)建的對(duì)象應(yīng)該盡快的去掉強(qiáng)引用。

d.正確處理App生命周期事件。當(dāng)進(jìn)入后臺(tái)時(shí),應(yīng)該保持應(yīng)用程序數(shù)據(jù),以便回到前臺(tái)時(shí)能夠恢復(fù)。當(dāng)進(jìn)入 inactive 狀態(tài)時(shí),應(yīng)該暫停當(dāng)前的業(yè)務(wù)流。iOS運(yùn)行App在后臺(tái)運(yùn)行的時(shí)間有限,因此后臺(tái)代碼不應(yīng)該執(zhí)行非常耗時(shí)的任務(wù),可能的話就使用多線程。當(dāng)進(jìn)入后臺(tái)時(shí),iOS會(huì)保存當(dāng)前App的一個(gè)快照,以便之后在合適的時(shí)候(裝載view和數(shù)據(jù)時(shí))呈現(xiàn)給用戶以提高用戶體驗(yàn),因此在進(jìn)入后臺(tái)時(shí),應(yīng)該避免在屏幕上呈現(xiàn)用戶信息,以免泄露用戶個(gè)人資料。

e.不要更新UI或者執(zhí)行大量消耗CPU或電池的代碼。進(jìn)入后臺(tái)之后,不應(yīng)該執(zhí)行不必要的任務(wù),不要執(zhí)行 OpenGL ES 調(diào)用,應(yīng)取消 Bonjour 相關(guān)的服務(wù),正確處理網(wǎng)絡(luò)鏈接失敗,避免更新 UI,清除所有的警告或其他彈出對(duì)話框。

f.在后臺(tái)時(shí)正確響應(yīng)系統(tǒng)變化。 如:

設(shè)備旋轉(zhuǎn)消息 UIDeviceOrientationDidChangeNotification

重要的時(shí)間變化(新的一天開始或時(shí)區(qū)變化)UIApplicationSignificantTimeChangeNotification

電池變化 UIDeviceBatteryLevelDidChangeNotification 和 UIDeviceBatteryStateDidChangeNotification

用戶默認(rèn)設(shè)置變化 NSUserDefaultsDidChangeNotification

本地化語言變化 NSCurrentLocaleDidChangeNotification 等。

g.保存用戶數(shù)據(jù)或狀態(tài)信息,所有沒寫到磁盤的文件或信息,在進(jìn)入后臺(tái)時(shí),最好都寫到磁盤去,因?yàn)槌绦蚩赡茉诤笈_(tái)被殺死。

applicationDidEnterBackgound: 方法有大概5秒的時(shí)間讓你完成自己的任務(wù)。如果超過時(shí)間還有未完成的任務(wù),你的程序就會(huì)被終止而且從內(nèi)存中清除。如果還需要長時(shí)間的運(yùn)行任務(wù),可以調(diào)用 beginBackgroundTaskWithExpirationHandler方法去請(qǐng)求后臺(tái)運(yùn)行時(shí)間和啟動(dòng)線程來運(yùn)行長時(shí)間運(yùn)行的任務(wù)。

6、處理內(nèi)存警告:iOS下每個(gè)app可用的內(nèi)存是被限制的,如果一個(gè)app使用的內(nèi)存超過了這個(gè)閥值,則系統(tǒng)會(huì)向該app發(fā)送Memory Warning消息。收到消息后,app必須盡可能多的釋放一些不必要的內(nèi)存,否則OS會(huì)關(guān)閉app。最佳方式是移除緩存、圖片對(duì)象和其他一些可以重創(chuàng)建對(duì)象的強(qiáng)引用。

處理內(nèi)存警告具體方法如下:

-(void)didReceiveMemoryWarning{[superdidReceiveMemoryWarning];//即使沒有顯示在window上,也不會(huì)自動(dòng)的將self.view釋放。// 保證是在6.0下使用的,6.0以前屏蔽以下代碼,否則會(huì)在下面使用self.view時(shí)自動(dòng)加載viewDidUnLoadif([[UIDevicecurrentDevice].systemVersion floatValue] >=6.0) {//需要注意的是self.isViewLoaded是必不可少的,其他方式訪問視圖會(huì)導(dǎo)致它加載if(self.isViewLoaded && !self.view.window)// 是否是正在使用的視圖{self.view =nil;// 目的是再次進(jìn)入時(shí)能夠重新加載調(diào)用viewDidLoad函數(shù)。}}}

二、緩存優(yōu)化:

1、iOS緩存優(yōu)化

盡量 cache 那些可重復(fù)利用的對(duì)象,緩存那些不大可能改變但是需要經(jīng)常讀取的東西,比如table cell、date/number formatters、遠(yuǎn)端服務(wù)器的響應(yīng)、圖片、甚至計(jì)算結(jié)果(UITableView的行高)等。

2、NSURLConnection

NSURLConnection默認(rèn)會(huì)緩存資源在內(nèi)存或者存儲(chǔ)中根據(jù)它所加載的HTTP Headers。

3、NSURLCache

iOS中緩存技術(shù)用到了NSURLCache類。

4、NSCache

NSCache是蘋果官方提供的緩存類,NSCache是線程安全的,在多線程操作中,不需要對(duì)Cache加鎖。NSCache的Key只是對(duì)對(duì)象的strong引用,對(duì)象不需要實(shí)現(xiàn)NSCopying協(xié)議,NSCache也不會(huì)像NSDictionary一樣復(fù)制對(duì)象。

5、兩種圖片加載方式

常見的從bundle中加載圖片的方式有兩種,一個(gè)是用imageNamed,二是用imageWithContentsOfFile。

imageNamed的優(yōu)點(diǎn)是當(dāng)加載時(shí)會(huì)緩存圖片,這個(gè)方法用,如果圖片存在的話,一個(gè)指定的名字在系統(tǒng)緩存中查找并返回一個(gè)圖片對(duì);如果緩存中沒有找到相應(yīng)的圖片,這個(gè)方法從指定的文檔中加載然后緩存并返回這個(gè)對(duì)象。而imageWithContentsOfFile僅加載圖片。如果你要加載一個(gè)大圖片而且是一次性使用,那么就沒必要緩存這個(gè)圖片,用imageWithContentsOfFile足矣,這樣不會(huì)浪費(fèi)內(nèi)存來緩存它。然而,在圖片反復(fù)重用的情況下imageNamed是一個(gè)好得多的選擇。

三、CPU緩存解析

四、iOS存儲(chǔ)優(yōu)化

使用最合適的數(shù)據(jù)存儲(chǔ)方式

NSUerDefaults:便捷,但是只適用于小數(shù)據(jù);

XML, JSON, 或者 plist:能處理大數(shù)據(jù),但需要讀取整個(gè)文件到內(nèi)存里去解析,浪費(fèi)資源;

NSCoding存檔:也需要讀取文件,具有同上的問題;

SQL數(shù)據(jù)庫或者 Core Data:使用這些技術(shù)比較好,用特定的查詢語句就能只加載需要的對(duì)象。

1)、Core Data使用分析:

a.概念:Core Date是對(duì)SQLite的封裝,提供了更高級(jí)的數(shù)據(jù)持久化解決方案。Core Data是完全獨(dú)立于任何UI層級(jí)的框架,它是作為模型層框架被設(shè)計(jì)出來的。在對(duì)數(shù)據(jù)庫操作時(shí),不需要使用sql語句,是一種ORM(“對(duì)象關(guān)系映射”)的數(shù)據(jù)庫操作方式,ORM將關(guān)系數(shù)據(jù)庫中的表,轉(zhuǎn)化為程序中的對(duì)象,但實(shí)際上是對(duì)數(shù)據(jù)中的數(shù)據(jù)進(jìn)行操作,按照面向?qū)ο蟮乃枷?,使用?shí)體模型來操作數(shù)據(jù)庫。使用Core Data進(jìn)行數(shù)據(jù)庫存取不需要手動(dòng)創(chuàng)建數(shù)據(jù)庫,創(chuàng)建數(shù)據(jù)庫的過程完全由Core Data框架自動(dòng)完成,開發(fā)者需要做的就是把模型創(chuàng)建起來,Core Data實(shí)際上是將數(shù)據(jù)庫的創(chuàng)建、表的創(chuàng)建、對(duì)象和表的轉(zhuǎn)換等操作封裝起來,以簡化我們的操作。如果模型發(fā)生了變化,可以選擇重新生成實(shí)體類文件,但是自動(dòng)生成的數(shù)據(jù)庫并不會(huì)自動(dòng)更新,需要考慮重新生成數(shù)據(jù)庫,并把之前數(shù)據(jù)庫中數(shù)據(jù)進(jìn)行移植。

b.優(yōu)勢:簡化操作。(特別是在App升級(jí)之后數(shù)據(jù)庫字段或者表有更改會(huì)導(dǎo)致crash)

c.劣勢:不支持跨平臺(tái)使用。

2)、SQL數(shù)據(jù)庫使用分析:

a.概念:Core Data代表一個(gè)對(duì)象的graph model(圖表模型),SQLite就是一個(gè)DBMS,也更加底層。使用SQLite,可以用FMDB這個(gè)庫來簡化SQLite的操作,節(jié)省了了解SQLite的C API的時(shí)間。

b.優(yōu)勢:支持跨平臺(tái)使用

c.劣勢:相對(duì)Core Data操作復(fù)雜

五、網(wǎng)絡(luò)請(qǐng)求優(yōu)化

1)、對(duì)請(qǐng)求壓縮:減小文檔的一個(gè)方式就是在服務(wù)端和你的app中打開gzip,這對(duì)于文字這種能有更高壓縮率的數(shù)據(jù)來說會(huì)有更顯著的效用。iOS已經(jīng)在NSURLConnection中默認(rèn)支持了gzip壓縮,當(dāng)然AFNetworking這些基于它的框架亦然。

2)、對(duì)數(shù)據(jù)壓縮:Web瀏覽器對(duì)請(qǐng)求壓縮的支持并不太好,因?yàn)闉g覽器不知道目標(biāo)服務(wù)器是否能夠支持對(duì)請(qǐng)求的解壓縮。所以Base64預(yù)先壓縮數(shù)據(jù)是個(gè)很好的方法,比如以Base64格式上傳JPEG文件,那么可以對(duì)Base64數(shù)據(jù)進(jìn)行壓縮,相較于未壓縮的Base64數(shù)據(jù),壓縮后的數(shù)據(jù)體積會(huì)降低30%左右。

3)、選擇合適的傳輸數(shù)據(jù)的方案:壓縮模式的效率在很大程序上取決于待壓縮的數(shù)據(jù),不過通常情況下JSON都是一種更為高效的模式。

4)、降低請(qǐng)求延遲:有兩項(xiàng)最佳實(shí)踐:

a.在單個(gè)TCP連接上發(fā)送HTTP請(qǐng)求,以管道的形式發(fā)送HTTP請(qǐng)求,從而優(yōu)化全雙工TCP連接的使用。Apache和IIS都支持管道,無需任何額外的配置。

b.通過HTTP緩存機(jī)制的基本原理,在iOS應(yīng)用中利用這些規(guī)則,可以在本地緩存內(nèi)容以避免不必要的網(wǎng)絡(luò)流量。如我們上面提到的NSURLCache、NSCache等。

5)、另外,優(yōu)化網(wǎng)絡(luò)請(qǐng)求的一環(huán)是DNS解析:因?yàn)榭蛻舳薬pp的請(qǐng)求第一步都是DNS解析,但由于cache的存在使得大部分的解析請(qǐng)求并不會(huì)產(chǎn)生任何延遲。所以,如果能直接跳過DNS解析這一步,當(dāng)然能提升網(wǎng)絡(luò)性能了。

a.一種方法是使用DNS映射。

b.另外就是直接用ip請(qǐng)求數(shù)據(jù)。DNS解析請(qǐng)求簡單來說,就是輸入一個(gè)域名,輸出一個(gè)ip地址。做自己的映射機(jī)制也就是客戶端本地維護(hù)這樣一個(gè)映射文件,只不過這個(gè)映射文件需要能從服務(wù)器更新,還要做一些容錯(cuò)處理。

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

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

  • 1. 用ARC管理內(nèi)存 ARC(Automatic ReferenceCounting, 自動(dòng)引用計(jì)數(shù))和iOS5...
    一杯冰可樂閱讀 1,732評(píng)論 1 12
  • 性能對(duì)iOS應(yīng)用的開發(fā)尤其重要,性能不佳會(huì)體現(xiàn)在:你的應(yīng)用失去反應(yīng)或者反應(yīng)很慢。 分為三個(gè)不同的等級(jí): 入門級(jí)、 ...
    goyohol閱讀 676評(píng)論 0 3
  • 謝瓊霞健康管理閱讀 158評(píng)論 0 0
  • 一大波學(xué)習(xí)資料來襲 開學(xué)已經(jīng)五周啦,期中考試也即將到來,同學(xué)們是否正帶著U盤四處探尋傳說中學(xué)長的學(xué)習(xí)資料呢?現(xiàn)在,...
    零度咖啡_a3ae閱讀 432評(píng)論 0 0
  • 人,在歷史的洪流里能起到什么樣的作用? 1 看了電影《一九四二》,心里久久不能平靜。其實(shí)很久以前,在06年左右,我...
    白秋練閱讀 489評(píng)論 0 0

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