2012-02-15 48 views
1

我有一個奇怪的問題,在循環中一個接一個地保存大量圖像(從相機)到文件系統。在iOS上一個接一個地保存大圖像內存釋放

如果我在每個循環中放置了[NSThread sleepForTimeInterval:1.0];,那麼每次圖像處理後都會釋放內存。但沒有睡眠時間間隔,內存分配增加到屋頂以上,最終應用程序崩潰...

有人請解釋如何避免這種情況或每個循環後釋放內存?

順便說一句,我在iOS 5開發...

這是我的代碼:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    for (NSDictionary *imageInfo in self.imageDataArray) { 

     [assetslibrary assetForURL:[NSURL URLWithString:imageUrl] resultBlock:^(ALAsset *asset) { 
      CGImageRef imageRef = [[asset defaultRepresentation] fullResolutionImage]; 
      if (imageRef) { 
       [sharedAppSettingsController saveCGImageRef:imageRef toFilePath:filePath]; 
       imageRef = nil; 
       [NSThread sleepForTimeInterval:1.0]; 
       //CFRelease(imageRef); 
      } 
     } failureBlock:^(NSError *error) { 
      NSLog(@"booya, cant get image - %@",[error localizedDescription]); 
     }]; 

    } 

    // tell the main thread 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     //do smth on finish 
    }); 
}); 

這是保存CGImage到FS的方法:

- (void)saveCGImageRef:(CGImageRef)imageRef toFilePath:(NSString *)filePath { 
    @autoreleasepool { 
     CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath]; 
     CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypeJPEG, 1, NULL); 
     CGImageDestinationAddImage(destination, imageRef, nil); 

     bool success = CGImageDestinationFinalize(destination); 
     if (!success) { 
      NSLog(@"Failed to write image to %@", filePath); 
     } 
     else { 
      NSLog(@"Written to file: %@",filePath); 
     } 
     CFRelease(destination); 
    } 
} 
+0

你是否將你的循環包裝在@autorelease {}塊中? – Nyx0uf 2012-02-15 13:06:42

+0

你可以發佈一些代碼 – 2012-02-15 13:24:32

+0

我已經將代碼封裝在循環內部和外部,沒有任何效果。應用程序仍然消耗超過20MB的內存和崩潰。還有什麼要尋找? – 2012-02-15 13:25:35

回答

2

問題是您在for循環中調用「assetForURL」。這種方法將開始在一個單獨的線程上同時加載所有圖像。您應該開始加載1個圖像,並在完成塊中繼續加載下一個圖像。我建議你使用某種遞歸。

+0

謝謝,那工作... – 2012-02-21 07:32:07

0

我剛剛發現問題不在於saveImageRef方法,但帶有ALAssetRepresentation對象:

CGImageRef imageRef = [[asset defaultRepresentation] fullResolutionImage]; 

imageRef從照片庫讀取每個原始圖像後分配大量的內存。這是合乎邏輯的。

但我希望這個imageRef對象在每個循環結束時釋放,而不是每當ARC決定釋放它時。

所以我試圖imageRef = nil;後每個循環,但沒有任何改變。

是否有任何其他方式釋放每個循環結束時分配的內存?