淺談 UIImage 內存管理問題

由于種種原因,簡書等第三方平臺博客不再保證能夠同步更新,歡迎移步 GitHub:https://github.com/kingcos/Perspective/。謝謝!

探究 iOS 中 UIImage 中兩種不同 Initializers 帶來的內存問題
本文使用 Swift 版本為 3.0 beta。

  • Info:
  • Swift 3.0 beta
  • Xcode 8.0 beta 5
  • macOS Sierra Public Beta 3

前言

近幾天接觸 iOS 的 UI 學習,由于 Swift 更新太快太頻繁,因此看的是 Obj-C 的項目,自己修改為 Swift 3.0 beta 可編譯運行的版本。Xcode 8.0 隨著幾個版本的更迭也趨于穩定,不過在不同 beta 版中,Swift 3.0 beta 的語法也略有改動,之前整理的 初探 Swift 3.0 系列也會略有過時了。這次是制作一個簡單的圖片瀏覽器,而且會動態的展示(偽) GIF 動畫,因此需要處理 animation 以及多張圖片。如果不進行適當的內存管理,那么大量的圖片占用內存,將使得程序在 iOS 設備上崩潰,造成極差的用戶體驗。因此本文淺顯地分析兩種不同的 UIImage 初始化方法,為以后的使用做以適當鋪墊。

不過,鑒于剛剛入門 iOS,所以某些行為或說法也許不太得當,需要學習的地方還有很多,故若有紕漏,還望指出。

init?(named: String)

Loading and Caching Images init?(named: String)
Returns the image object associated with the specified filename.
Discussion
This method looks in the system caches for an image object with the specified name and returns the variant of that image that is best suited for the main screen. If a matching image object is not already in the cache, this method locates and loads the image data from disk or from an available asset catalog, and then returns the resulting object.
The system may purge cached image data at any time to free up memory. Purging occurs only for images that are in the cache but are not currently being used.
In iOS 9 and later, this method is thread safe.
Special Considerations
If you have an image file that will only be displayed once and wish to ensure that it does not get added to the system's cache, you should instead create your image using imageWithContentsOfFile:. This will keep your single-use image out of the system image cache, potentially improving the memory use characteristics of your app.

加載并緩存圖像 init?(named: String)
返回指定文件名所關聯的圖像對象。
論述
該方法在系統緩存中尋找指定名稱的圖像對象,并返回最適合主屏幕的圖像的變體。若對應的圖像對象已不存在于緩存,則該方法將在磁盤或存在的資源目錄中定位并載入圖像數據,并返回結果對象。
系統可能隨時清空圖像數據以釋放內存。清空操作只會發生在處于緩存但當前未被使用的圖像。
在 iOS 9 及以上版本,該方法是線程安全的。
特殊考慮
如果圖像文件只需顯示一次,且希望確保其不會被添加到系統的緩存中,你應當使用 imageWithContentsOfFile: 方法。該方法將保證其在系統圖像緩存以外的單一使用,潛在提升 app 的內存使用特性。

init?(contentsOfFile: String)

Creating and Initializing Image Objects init?(contentsOfFile: String)
Initializes and returns the image object with the contents of the specified file.
Discussion
This method loads the image data into memory and marks it as purgeable. If the data is purged and needs to be reloaded, the image object loads that data again from the specified path.

創建并初始化圖像對象 init?(contentsOfFile: String)
初始化并返回指定文件內容的圖像對象。
論述
該方法加載圖像數據到內存,并標記其可以被清空。如果數據被清空,需要重新載入,圖像對象將會從指定路徑再次加載數據。

Demo

如蘋果官方文檔所述,這兩個 Initializer 雖然都是加載圖片,但是一個做了緩存,另一個并沒有。所以 init?(named: String) 更適合加載 icon 等占用小的圖片,而 init?(contentsOfFile: String) 適合較大的圖片。

// init?(named: String)
let demoIcon = UIImage(named: "DemoIcon")

// init?(contentsOfFile: String)
let demoImagePath = Bundle.main.path(forResource: "DemoImage.png", ofType: nil)
let demoImage = UIImage(contentsOfFile: demoImagePath ?? "")

init?(named: String) 常用于加載小且常用的 icon,其初始化的圖片,占用的緩存只會在程序退出時才清空,即使消除強引用仍會占用緩存。而 init?(contentsOfFile: String) 初始化的圖片,在沒有強引用時便會自動銷毀。

init?(contentsOfFile: String) 使用有一些注意點。該方法的參數是圖片的全路徑,所以需要通過 Bundle 來獲取,而且需要帶上后綴名。需要注意的是,如果圖片放置在 Assets.xcassets 中,Bundle 是無法獲取到的,需要直接復制到項目中。否則的話 demoImagePath 將為 nil,導致無法獲取到圖片,程序也將可能崩潰。

參考資料

Xcode Documentation & API Reference

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

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,170評論 4 61
  • 嗯哼嗯哼蹦擦擦~~~ 轉載自:https://github.com/Tim9Liu9/TimLiu-iOS 目錄 ...
    philiha閱讀 4,982評論 0 6
  • 環保對于我們來說是非常重要的,我們要從小事做起。不亂扔垃圾節約用水用電養成好習慣,珍惜自然資源愛護花花草草。我們才...
    翔翔要努力閱讀 185評論 0 0
  • 春節前后,老公腹部不適,伴有腹痛和發燒,臉色發青,人也消瘦了不少。我預感到:二十一前的那病魔又重來了! 二十一...
    祁鷹閱讀 708評論 5 3
  • 弗洛伊德在《文明及其不滿》中說,“人類不幸的根源之一是由壓抑本能造成。”而在釋放本能,使其無阻礙時,幸福與不幸又...
    婕福濟拼閱讀 169評論 3 1