2013-06-24 64 views
0

我正在以10MB塊的形式讀取我的磁盤上的文件(大小可能小於幾GB),以便爲其驗證MD5。方法fetchRecords已被簡化,因爲它是一個bi即使在讀取文件的同時釋放內存時,也需要釋放內存到NSData


t long。問題在於,當fetchRecords方法返回時,數據被釋放,屆時我在內存中只有幾GB。如果文件足夠大,會導致崩潰。最後[dataChunk release]沒有幫助。在返回之前獲得大量不活動的內存。

enter image description here enter image description here

- (void)fetchRecords 
{  
    for (DownloadChunkInfo *downloadChunkInfo in [downloadFileInfo chunk]) 
    { 
     NSData *dataChunk = [NSData dataWithContentsOfFile:fileDownloadPath withStartOffset:[downloadChunk startingByte] andEndOffset:[downloadChunk endingByte]]; 
     if ([dataChunk length] == [downloadChunk length]) 
     { 
      if ([downloadChunk md5] && [[dataChunk MD5] isEqualToString:[downloadChunk md5]]) 
      { 
       // Some code 
      } 
      else 
      { 
       // Some code 
      } 
     } 
     [dataChunk release]; 
    } 
} 

+ (NSData *)dataWithContentsOfFile:(NSString *)path withStartOffset:(off_t)startOffset andEndOffset:(off_t)endOffset 
{ 
    FILE *file = fopen([path UTF8String], "rb"); 
    if(file == NULL) 
     return nil; 
    uint64_t size = (endOffset - startOffset) + 1; 
    void *data = malloc(size); // check for NULL! 
    fseeko(file, startOffset, SEEK_SET); 
    size_t realSize = fread(data, 1, size, file); // check return value, in case read was short! 
    fclose(file); 

    // NSData takes ownership and will call free(data) when it's released 
    return [NSData dataWithBytesNoCopy:data length:realSize]; 
} 

回答

3

[dataChunk release]其實是錯誤的,因爲你不 「自己」 的對象由

NSData *dataChunk = [NSData dataWithContentsOfFile:...]; 

返回值是(須經成爲可能的優化返回編譯器) 「自動釋放」對象,僅噹噹前自動釋放池 被銷燬時釋放。

因此,使用本地自動釋放池應該有所幫助:

for (DownloadChunkInfo *downloadChunkInfo in [downloadFileInfo chunk]) 
{ 
    @autoreleasepool { 
     NSData *dataChunk = [NSData dataWithContentsOfFile:fileDownloadPath withStartOffset:[downloadChunk startingByte] andEndOffset:[downloadChunk endingByte]]; 
     // do something with dataChunk ... 
    } 
} 

欲瞭解更多信息,請參閱

在「高級內存管理編程指南「瞭解更多信息。