0

我正在以 10MB 的块读取磁盘上的文件(大小可能为几 GB),以验证它的 MD5。方法 fetchRecords 已被简化,因为它是一个双


长。问题是当 fetchRecords 方法返回时数据被释放,那时我的内存只有几 GB。如果文件足够大,则会导致崩溃。[dataChunk release]最后没有帮助。获得大量非活动内存,直到它返回。

在此处输入图像描述 在此处输入图像描述

- (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];
}
4

1 回答 1

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 ...
    }
}

有关详细信息,请参阅

在“高级内存管理编程指南”中了解更多信息。

于 2013-06-24T13:11:39.897 回答