0

MD5 を検証するために、ディスク上のファイル (サイズは数 GB になる可能性があります) を 10 MB のチャンクで読み込んでいます。メソッド fetchRecords は、bi であるため簡略化されています。


長い。問題は、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 ...
    }
}

詳細については、次を参照してください。

詳細については、『Advanced Memory Management Programming Guide』を参照してください。

于 2013-06-24T13:11:39.897 に答える