2011-05-23 50 views
0

在我的應用程序中,我動態創建一個大圖像,然後將其加載顯示在我的圖像瀏覽器類中。因爲我無法在運行時向包添加新圖像,所以似乎必須使用imageWithContentsOfFile - 但是,這給我帶來了重大的速度問題。imageWithContentsOfFile的主要速度問題

我的圖像瀏覽器工作的方式是它將圖像分解成多個圖塊,緩存這些圖塊,然後只將這些圖塊加載到內存中以供顯示,這些圖塊需要在屏幕上顯示。使用一堆NSLogs,我已經設法找出所有放緩的地方。這不是在imageWithContentsOfFile功能本身,這是當我嘗試調用這一行:

CGContextDrawImage(context_ref, 
        CGRectMake(0, 0, imgWidth, imgHeight), tileImage); 

這是當我寫了瓷磚的緩存文件。 tileImage是從CGImageCreateWithImageInRect返回的CGImageRef,這是我如何獲得大圖像的子集以單獨保存。

奇怪的是,以這種方式分割大圖像需要大約45秒(!),但是當我使用imageNamed而不是imageWithContentsOfFile從包中分離圖像時,它只需要大約2秒。

任何人有任何想法?在此先感謝:)

+0

我真的*建議刪除所有這些日誌,並使用探查器來推斷您的時間實際上花費在哪裏。一堆日誌只會減慢速度,掛鐘時間對於你的問題是非常不準確的。 – justin 2011-05-23 03:00:24

+0

相信我,這不是減慢速度的日誌 - 在我上面發佈的每個平局調用中,都會等待大約500毫秒,並且我爲每個平鋪打一個電話(可以有多達200個平鋪每張圖片)。當我交換到imageNamed時,繪圖調用佔用了一小部分時間。 – Adam 2011-05-23 05:48:23

+0

我的主要觀點並不是我不相信你,或者那個日誌是你的問題(在分析過程中只需要省略日誌記錄,在測量時間/速度時不要使用日誌記錄,也不要使用掛鐘分析 - esp當優越的選擇存在時)。我的主要觀點是,樂器會告訴你花了多少時間,花在哪裏。只是比較使用這兩種實現的樣本,並且您的答案可能很明顯。證據和證據打敗猜測。 – justin 2011-05-23 06:16:57

回答

0

我認爲你應該分裂你的形象。 因爲,CGContextDrawImage將完全加載「tileImage」。

如果您的「tileImage」大小爲8 MB,則您的應用必須將8MB數據加載到內存。 加載需要很長時間。並可能造成內存問題等。

如果你想使用一個大的圖像,你可以等待加載, 有解決方案,U可以使用另一個線程。

它可以避免在加載大圖像時發生UI鎖定。

8MB JPG圖像將使用超過8MB內存,UIImage應使用非壓縮格式進行快速繪製。

0

imageNamed使用緩存,並可能減少縮放量。

UIImage是不可變的。 imageNamed可能會注意到這一點,並返回對緩存圖像的引用,而不是加載並創建新圖像......無論您加載圖像的位置如何。

如果您創建圖像,則可以在許多情況下設置自己的(內存中)緩存方案並傳遞引用。然後在收到內存警告時清除緩存。

如果您需要縮放圖像並且尺寸是靜態的,請確定要繪製的尺寸並使用imageWithCGImage:scale:orientation:創建UIImage - 或者您也可以使用CoreGraphics apis以類似的方式直接處理問題。

除此之外,堅持/重用您需要的內容,並使用分析器來平衡您的分配並衡量計時。