iOS 優化內存的方法


1.把views設置為透明,透明的Views你應該設置它們的opaque屬性為YES。

原因是這會使系統用一個最優的方式渲染這些views。這個簡單的屬性在IB或者代碼里都可以設定。

Apple的文檔對於為圖片設置透明屬性的描述是:

(opaque)這個屬性給渲染系統提供了一個如何處理這個view的提示。如果設為YES,渲染系統就認為這個view是完全不透明的,這使得渲染系統優化一些渲染過程和提高性能。如果設置為NO,渲染系統正常地和其它內容組成這個View。默認值是YES。該屬性為BOOL值,UIView的默認值是YES,但UIButton等子類的默認值都是NO.

在相對比較靜止的畫面中,設置這個屬性不會有太大影響。然而當這個view嵌在scroll view里邊,或者是一個復雜動畫的一部分,不設置這個屬性的話會在很大程度上影響app的性能。

你可以在模擬器中用Debug\Color Blended Layers選項來發現哪些view沒有被設置為opaque。目標就是,能設為opaque的就全設為opaque!

2.對於僅使用一次或是使用頻率很低的大圖片資源不要使用UIImage(named: "")而使用UIImage(contentsOfFile: "")

UIImage(named: "")返回的對象會保存在緩存中,只有退出程序才會釋放內存;但下一次調用快,UIImage(contentsOfFile: "")返回的對象不會保存在緩存中,一旦對象銷毀就會釋放內存

3.一些圖片本身非常適合用9片圖的機制進行拉伸,但沒有進行相應的優化

圖片的內存占用是很大的,對於適合用9片圖機制進行拉伸處理的圖片,可以切出一個比實際尺寸小的多的圖片,從而大量減少內存占用。我們可以利用Xcode的slicing功能,設定圖片哪些部分不進行拉伸,哪些部分進行拉伸。在加載圖片的時候,還是以正常的方式進行加載。

4.基於顏色創建純色的圖片時,尺寸過大

有時,我們需要基於顏色創建出UIImage,並用做UIButton在不同狀態下的背景圖片。由於是純色的圖片,那么,我們完全沒有必要創建出和視圖大小一樣的圖像,只需要創建出寬和高均為1px大小的圖像就夠了
5.在自定義的UIView子類中,利用drawRect:方法進行繪制改為CAShapeLayer

自定義drawRect會使APP消耗大量的內存,視圖越大,消耗的越多。其消耗內存的計算公式為:
消耗內存 = (width * scale * height * scale * 4 / 1024 / 1024)MB

大部分情況下,繪制需求都可以通過CAShapeLayer實現,CAShapeLayer屬於CoreAnimation框架,通過GPU來渲染圖形,節省性能。動畫渲染直接提交給手機GPU,不消耗內存

渲染快速。CAShapeLayer使用了硬件加速,繪制同一圖形會比用Core Graphics快很多。

高效使用內存。一個CAShapeLayer不需要像普通CALayer一樣創建一個寄宿圖形,所以無論有多大,都不會占用太多的內存。

不會被圖層邊界剪裁掉。

不會出現像素化。

6.在Image Views中調整圖片大小

如果要在`UIImageView`中顯示一個來自bundle的圖片,你盡量保證圖片的大小和UIImageView的大小相同。在運行中縮放圖片是很耗費資源的,特別是`UIImageView`嵌套在`UIScrollView`中的情況下。

如果圖片是從遠端服務加載的你不能控制圖片大小,比如在下載前調整到合適大小的話,你可以在下載完成后,最好是用background thread,縮放一次,然后在UIImageView中使用縮放后的圖片。

7.UILabel尺寸過大,為UILable設置背景色
如果一個UILabel的尺寸,大於 ContentSize,那么會引起不必要的內存消耗。所以,在視圖布局的時候,我們應該盡量使UILabel的尺寸等於其 ContentSize
如果設置的背景色不是clearColor, whiteColor,會引起內存開銷。可以將視圖結構轉變為 UIView+UILabel,為UIView設定背景色,而UILabel只是用來顯示文字,這樣可以減少內存開銷
8.高清大圖片的處理,
網絡下載高清大圖片時,禁止解壓
9.第三方庫的緩存機制,適時緩存,適時清除
(1)Lottie動畫框架
Lottie框架默認會緩存動畫幀等信息,如果一個應用中使用動畫的場合很多,那么隨着時間的積累,就會存在大量的緩存信息。然而,有些緩存信息可能以后再也不會被用到了,例如閃屏頁的動畫引起的緩存。針對Lottie的緩存引起的內存占用,可以根據自己的意願,選擇如下兩種處理辦法:
    1.禁止緩存 LRUAnimationCache.sharedCache.cacheSize = 0 緩存個數設置為零直接不緩存
    2.適當的地方清除緩存 LRUAnimationCache.sharedCache.clearCache()
(2)圖像緩存框架,如
SDWebImage的緩存機制,分為Disk和Memory兩層,Memory這一層使得圖片在被訪問時可以免去文件IO過程,提高性能。默認情況下,Memory里存儲的是解壓后的圖像數據,這個會導致巨大的內存開銷。如果想要優化內存占用,可以選擇存儲壓縮的圖像數據,在應用啟動的地方加如下代碼
[SDImageCache sharedImageCache].config.shouldDecompressImages = NO;
[SDWebImageDownloader sharedDownloader].shouldDecompressImages = NO;
10.重用和延遲加載(lazy load) Views

更多的view意味着更多的渲染,也就是更多的CPU和內存消耗,對於那種嵌套了很多view在UIScrollView里邊的app更是如此。

這里我們用到的技巧就是模仿`UITableView`和`UICollectionView`的操作:不要一次創建所有的subview,而是當需要時才創建,當它們完成了使命,把他們放進一個可重用的隊列中。

這樣的話你就只需要在滾動發生時創建你的views,避免了不划算的內存分配。

創建views的能效問題也適用於你app的其它方面。想象一下一個用戶點擊一個按鈕的時候需要呈現一個view的場景。有兩種實現方法:

1. 創建並隱藏這個view當這個screen加載的時候,當需要時顯示它;

2. 當需要時才創建並展示。

每個方案都有其優缺點。用第一種方案的話因為你需要一開始就創建一個view並保持它直到不再使用,這就會更加消耗內存。然而這也會使你的app操作更敏感因為當用戶點擊按鈕的時候它只需要改變一下這個view的可見性。

第二種方案則相反-消耗更少內存,但是會在點擊按鈕的時候比第一種稍顯卡頓。






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM