使用MoveItemAtPath进行内存峰值

时间:2011-10-10 19:19:43

标签: iphone objective-c ios

我正在使用照片选择器浏览和选择视频,一旦选中,我就将其从临时存储移动到我的工作目录中以备将来使用。我使用以下行执行此操作:

[[NSFileManager defaultManager] moveItemAtPath:newName toPath:newPath error:nil];

当我分析应用程序时,在此过程中,内存使用量会突然增加到视频文件的大小,然后稍后退回。有没有办法在没有内存峰值的情况下移动此文件?如果用户的设备当时运行了很多应用程序,我担心我的应用程序崩溃。

如果它有助于我的路径如下: /private/var/mobile/Applications/046F9A22-DBEC-436F-936C-D59945783483/tmp//trim.PK4abv.MOV

/private/var/mobile/Applications/046F9A22-DBEC-436F-936C-D59945783483/Documents/resources/myCards/BC742DC8-A7D4-40B8-8AC8-97CF9F242881/trim.PK4abv.MOV

2 个答案:

答案 0 :(得分:0)

你在不同的卷“移动”吗?如果是这样,则NSFileManager会将文件复制到目标并删除原始文件。此副本可能会导致“内存峰值”。

答案 1 :(得分:0)

如果内存峰值与文件大小相当,则可能是因为它将整个文件加载到内存中,如果文件大小变大,确实会导致问题。我处理这个问题的方式(复制/附加到文件时)是将文件移动到很少的块中,就像这样(旧的C文件API):

#import <sys/stat.h>

+(BOOL) moveFileAtPath:(NSString*)sourcePath 
          toFileAtPath:(NSString*)targetPath 
      inChunksWithSize:(size_t)bytes {

    // open target file for appending
    FILE *targetFile = fopen([targetPath UTF8String], "a");
    if(targetFile == NULL)
        return NO;

    FILE *sourceFile = fopen([sourcePath UTF8String], "rb");
    if(appendFile == NULL) {
        fclose(targetFile);
        return NO;
    }

    void *data = malloc(bytes); 
    if (data == NULL) {
        fclose(targetFile);
        fclose(sourceFile);
        return NO;
    }

    size_t sourceSize = (size_t)filelength(fileno(sourceFile));
    off_t currentOffset = 0;

    while (currentOffset < sourceSize) {
        fseeko(sourceFile, currentOffset, SEEK_SET);
        size_t read_bytes = fread(data, 1, bytes, sourceFile);
        fwrite(data, 1, read_bytes, targetFile);
        currentOffset += read_bytes;
        if (read_bytes < 1)
            break;
    }

    free(data);
    fclose(targetFile);
    fclose(sourceFile);

    return YES;
}