構建內存高效的應用

作者:Thomas Hanning,原文鏈接,原文日期:2015/08/06
譯者:BridgeQ;校對:lfb-CD;定稿:shanks

近年來,移動設備的性能越來越強大。然而,同桌面電腦相比,性能上總還是有一段不小的差距。同時,用戶界面和交互設計的要求也越來越高。所以,為移動設備編寫內存高效的應用仍然很有必要。

什么是內存高效的應用

通俗點講,內存高效的應用是指:僅使用必要的內存消耗并盡量減少內存消耗;用戶界面設計使用低內存消耗的框架。當然,一個復雜度更高的應用也肯定需要更高的內存消耗。

接下來我們首先來回顧一小段歷史:

自動引用計數(ARC:Automatic Reference Counting)

在早期的 iOS 開發中,內存管理扮演著非常重要的角色。因為傳統的垃圾回收機制對于移動平臺來說是非常低效的,所以蘋果把內存管理的責任交給了開發者,你需要通過手動的方式來增加或減少一個對象的引用計數。

通過這種方式,你可以寫出內存管理非常高效的應用,因為對象不再使用時就立刻被銷毀了。但另一方面,很多時候手動管理內存并不容易,也經常產生一些不易被發現的bug。所以,這并不是解決內存管理問題的最好辦法。

新的解決方案是在 iOS 5 中被提出的:自動引用計數(ARC)。從此之后,控制引用計數的命令會在編譯期間被自動加入而無需手動編寫。這樣帶來的好處是:一方面能編寫出內存高效的代碼,另一方面讓開發者不用再關心內存管理問題。這個解決方案非常棒,以至于 Mac OS X 的應用程序也開始使用 ARC 來管理內存。

不過,盡管你不需要再關心引用計數了,但還是需要你去關心一些其他內存管理相關的知識點。

選擇合適的部署版本

正如前文所說,不同的需求意味著應用的內存消耗也不盡相同,除此之外,不同的需求還意味著應用適應于不同的部署版本(應用運行所支持的最低系統版本)。舉個栗子,如果你的部署版本是 iOS 5,那么你就不能忘了要支持第一代 iPad 產品,它的內存大小僅僅是 256 MB。雖然,支持盡可能多的版本是一種不錯的選擇,但是,在你所支持的版本上為用戶帶來良好的用戶體驗才是更重要的。所以,當你想支持一些舊設備的時候,在設計階段就要仔細考慮內存消耗問題。

下面列舉了不同系統版本所支持的一些舊設備:

  • iOS 9: iPhone 4S / iPad 2 / iPad Mini 1
  • iOS 8: iPhone 4S / iPad 2 / iPad Mini 1
  • iOS 7: iPhone 4 / iPad 2 / iPad Mini 1
  • iOS 6: iPhone 3GS / iPad 2/ iPad Mini 1
  • iOS 5: iPhone 3GS / iPad 1 / –

由于蘋果的生態系統更新速度比較快,所以支持最新的兩代操作系統版本是一個很好的選擇。除了內存方面的問題,支持過多的系統版本還會帶來開發和測試等諸多方面的問題。

圖片資源

在移動應用中,圖片是非常重要的資源。然而,圖片也通常代表著高內存消耗。在處理圖片資源的時候,有以下兩點需要注意:

  • 首先,圖片應該有合適的尺寸。如果你有一個表格視圖,上面需要 100 × 100 像素的圖片,而你卻使用 1000 × 1000 像素的圖片,這一定是一個非常糟糕的作法,性能會受到非常大的影響。如果你是通過請求服務器獲取的圖片,那么服務器也應該進行處理以提供合適尺寸的圖片。
  • 其次,一定要保證圖片只是在需要使用的時候才被加載。舉個栗子,表格視圖里的圖片只有當單元格顯示出來的時候才需要被加載,也就是說單元格是可以循環利用的。想象一下,如果你的表格視圖有 5000 個單元格并在進入屏幕的時候全部被加載,這樣的話,即使你的應用沒有因為內存壓力而崩潰,用戶體驗也一定會非常的糟糕。你自定義的視圖也同樣應該遵守這一原則。再舉個栗子,如果你在開發一個相冊類應用,不要一口氣把所有圖片都加載完,你只需加載顯示在屏幕上的那些圖片就夠了。這種技術也通常被稱作延遲加載(lazy loading)。

延遲加載(lazy loading)

延遲加載技術的主旨就是盡可能晚地去加載資源,這樣會帶來以下兩點優勢:

  • 可以更好地來分配不同的加載時間
  • 可以避免加載那些可能不需要的資源

那么在 iOS 開發中如何使用延遲加載技術呢?正如前文提到的,表格視圖就是一個很好的使用延遲加載技術的栗子。另一種使用延遲加載的方法是使用lazy關鍵字來修飾屬性。想象一下你需要一個包含所有產品的數組,當用戶進行一定交互時需要使用到它們。

var products: [Products] = modelClass.loadProducts()

如上代碼,這個數組即使在用戶沒有進行任何交互的情況下仍然會被加載,這是一種內存浪費。如果加上lazy關鍵字進行修飾,那么只有在用戶第一次訪問數組的時候它才會初始化。

lazy var products: [Products] = modelClass.loadProducts()

即使只是一些小的數組和變量,合理地使用延遲加載技術也能節省很大一部分內存。

視圖控制器和循環引用

在所有內存問題中最壞的一種情況就是視圖控制器不再需要的時候卻沒有被釋放,出現這種情況最通常的原因是循環引用。試想一下,現在有一個控制器 A,它擁有一個控制器 B 作為它的子控制器,而且,控制器 B 還有一個指向控制器 A 的引用,這樣它們都互相強引用著對方。

現在,即使控制器 A 從屏幕中離開,兩個控制器也不會被釋放,因為它們還都強引用著對方。要避免這種情況你可以使用weak關鍵字。舉個栗子,想要將控制器 A 設置為控制器 B 的代理,正確的屬性聲明應該如下所示:

weak var delegate: DelegateType?

如果想檢查控制器是否被正確釋放,可以在控制器的deinit方法中打印消息來查看,代碼如下:

deinit {
     println("deinit")
}

接下來你就可以通過在控制臺中觀察,是否有輸出來檢查控制器對象是否被正確釋放。比如說,當你的控制器是被導航控制器通過push方法展現出來的時候,如果你點擊了導航條上的返回按鈕,控制器應該被釋放并且在控制臺中輸出信息。

監測你的內存使用量

我們通常是在項目開發的最后階段才發現內存管理的很糟糕,不幸的是,這樣已經太晚了。所以在項目開發過程中,經常對內存使用量進行監測是非常重要的。你只需在一臺真機上運行你的應用,然后點擊Xcode中調試選項卡下的Memory

總結

內存管理在移動開發領域是一個非常重要的話題。如果你使用了過多的內存消耗,應用就會變慢甚至可能崩潰。相反,如果你認真對待內存管理問題,你就會構建出內存高效的應用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,151評論 4 61
  • 2017年10月9日如是家人溫玲,種種子第70天 發心:我今不是為了我個人而聞思修,而是為了六道輪回一切如母有情眾...
    溫馨霏玲閱讀 216評論 2 4
  • 你看不起他! 但沒辦法,這就是特權! 要不你努力超越他! 要不你就被長期壓制,無法反抗!
    繁華似簡閱讀 157評論 0 0
  • Appium適配Android7.0以上版本 測試機型: 華為榮耀V9 安卓版本: Android7.0 appi...
    米洛丶閱讀 1,158評論 9 2