UIImage 載入效能優化

2021-07-11 00:21:48 字數 3004 閱讀 8067

uiimage 存在 延遲解壓的問題。這會占用時間。

一旦檔案被載入就必須要進行解碼,解碼過程是乙個相當複雜的任務,需要消耗非常長的時間。解碼後的將同樣使用相當大的記憶體。

用於載入的cpu時間相對於解碼來說根據格式而不同。對於png來說,載入會比jpeg更長,因為檔案可能更大,但是解碼會相對較快,而且xcode會把png進行解碼優化之後引入工程。jpeg更小,載入更快,但是解壓的步驟要消耗更長的時間,因為jpeg解壓演算法比基於zip的png演算法更加複雜。

當載入的時候,ios通常會延遲解壓的時間,直到載入到記憶體之後。這就會在準備繪製的時候影響效能,因為需要在繪製之前進行解壓(通常是消耗時間的問題所在)。

解決方法:

1.  使用uiimage+imagenamed:方法避免延時載入。這個方法會在載入之後立刻進行解壓(就和本章之前我們談到的好處一樣)。問題在於+imagenamed:

+imagewithcontentsoffile:(和其他別的uiimage載入方法)不是這樣的。

2.把它設定成圖層內容,或者是uiimageviewimage屬性。不幸的是,這又需要在主線程執行,所以不會對效能有所提公升。

3 繞過uikit,像下面這樣使用imageio框架:

這樣就可以使用kcgimagesourceshouldcache來建立,強制立刻解壓,然後在的生命週期保留解壓後的版本。

nsinteger index = indexpath.row;

nsurl *imageurl = [nsurl fileurlwithpath:self.imagepaths[index]];

nsdictionary *options = @; 

cgimagesourceref source = cgimagesourcecreatewithurl((__bridge cfurlref)imageurl, null);

cgimageref imageref = cgimagesourcecreateimageatindex(source, 0,(__bridge cfdictionaryref)options);

uiimage *image = [uiimage imagewithcgimage:imageref]; 

cgimagerelease(imageref);

cfrelease(source);

4 .使用uikit載入,但是立刻繪製到cgcontext中去。必須要在繪製之前解壓,所以就強制了解壓的及時性。這樣的好處在於繪製可以再後台執行緒(例如載入本身)執行,而不會阻塞ui。

有兩種方式可以為強制解壓提前渲染:

總之:如果不使用+imagenamed:,那麼把整張繪製到cgcontext可能是最佳的方式了。儘管你可能認為多餘的繪製相較別的解壓技術而言效能不是很高,但是新建立的(在特定的裝置上做過優化)可能比原始繪製的更快。

同樣,如果想顯示到比原始尺寸小的容器中,那麼一次性在後台執行緒重新繪製到正確的尺寸會比每次顯示的時候都做縮放會更有效(儘管在這個例子中我們載入的呈現正確的尺寸,所以不需要多餘的優化)。

如果修改了-collectionview:cellforitematindexpath:方法來重繪(清單14.3),你會發現滑動更加平滑。

5. catiledlayer

catiledlayer可以用來非同步載入和顯示大型,而不阻塞使用者輸入。但是我們同樣可以使用catiledlayeruicollectionview中為每個**建立分離的catiledlayer例項載入傳動器,每個**僅使用乙個圖層。

這樣使用catiledlayer有幾個潛在的弊端:

我們來看看這些弊端有沒有造成不同:清單14.4顯示了使用catiledlayer對傳送器的重新實現。

#import "viewcontroller.h"
#import
@inte***ce viewcontroller()
@property (nonatomic, copy) nsarray *imagepaths;

@property (nonatomic, weak) iboutlet uicollectionview *collectionview;

@end@implementation viewcontroller
- (void)viewdidload

- (nsinteger)collectionview:(uicollectionview *)collectionview numberofitemsinsection:(nsinteger)section

- (uicollectionviewcell *)collectionview:(uicollectionview *)collectionview cellforitematindexpath:(nsindexpath *)indexpath

//tag the layer with the correct index and reload

tilelayer.contents = nil;

[tilelayer setvalue:@(indexpath.row) forkey:@"index"];

[tilelayer setneedsdisplay];

return cell;

}

- (void)drawlayer:(catiledlayer *)layer incontext:(cgcontextref)ctx

@end

需要解釋幾點:

UIImage 載入方式及優化

一 載入方式 1.快取載入方式 uiimage image uiimage imagenamed imagefilename 載入後,會自動加入系統快取中,並不會立即釋放到記憶體。加快程式的執行減少io操作,但對於專案中只用到一次的,會導致程式的記憶體使用增加。2.非快取載入方式 uiimage i...

CSS載入效能優化

將首屏頁面要用到的css檔案,放在頁面頭部載入,其他模組的css可以使用非同步載入 loadcss 和 preload。1 通過rel preload 進行內容預載入 2 preload 的w3文件 對於一些不是首屏載入的css,我們可以如下寫法 preload href path to haoro...

細講UIImage載入方式

原文 關於本地uiimage的載入問題,還是需要注意的。不同的載入處理方式,在效率和效能上還是有差異的。今天,我們來講講uiimage的載入應該選擇什麼樣的api來載入!這兩種api分別是 大量使用 initwithcontentsoffile 方式來載入,會增加cpu的開銷,所以我們需要根據特定場...