你的數據集是相當大的在這裏。在圖像解壓縮之後考慮它:1136高度x 640寬度x每個像素4個字節x 110個圖像= 320MB。不幸的是,圖像解壓縮不是快速/免費的,所以如果你希望這種情況發生在50Hz,你將不得不玩一些技巧。對於初學者來說,您可能無法同時將所有110張圖像保存在內存中,因此請不要試圖這樣做。另外,請不要使用-[UIImage imageNamed:]
。它以一種無法控制的方式積極緩存圖像的解壓縮版本。我會使用[[UIImage alloc] initWithContentsOfFile:]
,以便最大限度地控制圖像的生命週期。
如果解壓縮時間是可以容忍的,那麼它可能就像保留一組圖像路徑一樣簡單,然後在最後一分鐘內製作一個需要的對象。我懷疑20毫秒會有點太慢,每次解壓縮。
另一種選擇是預解壓縮圖像,然後將解壓縮的數據寫入磁盤上應用程序的緩存目錄。這樣,你仍然從磁盤加載,但它是一個直讀,而不是每次讀取和解壓縮。請注意,這將消耗〜320MB的磁盤存儲空間。不是太太可怕了。
爲了更進一步,有一些額外的詭計,你可能能夠得到它,因此圖像在磁盤上,然後應用程序中的圖像對象可以指向與每個圖像對應的mmap存儲區域磁盤上的文件。這樣你就可以讓虛擬內存系統決定什麼是重要的內存,什麼不重要,你可以免費獲得。這似乎可能是最好的拍攝。 (編輯:我看了,看起來UIImage已經在後臺映像了,所以這個建議可能對你沒有太大的幫助。)
只是我從你發佈的代碼片段中注意到的一件事:你捕獲整個這意味着陣列中的每個圖像在該塊的持續時間內保持活動(並且一段時間更長,直到libdispatch決定釋放塊)。它可能不會足夠以避免這(因此我的建議如上),但它肯定無助於捕捉整個陣列。這就是我的意思:
[audioUnit setOutputBlock:^() {
@autoreleasepool {
NSArray* images = [NSArray array]; // or whatever
// ...
// some heavy calculations
// ...
UIImage* theOneImageWeNeed = images[index];
}
dispatch_sync(dispatch_get_main_queue(), ^{
imageView.image = theOneImageWeNeed;
});
}];
這將保持你需要的一個圖像活着,並積極釋放由計算生成的任何其他對象。
您設置的圖像是什麼?圖像是否已經加載到內存中? – Wain
圖像是110 UIImages的數組,每個圖像分辨率爲1136×640,大小約爲20kb;我已經嘗試加載它們與imageNamed以及imageWithContentsOfFile ..相同的結果。 – DAN