MoveItemAtPath 的内存峰值
Posted
技术标签:
【中文标题】MoveItemAtPath 的内存峰值【英文标题】:Memory spike with MoveItemAtPath 【发布时间】:2011-10-10 19:19:42 【问题描述】:我正在使用照片选择器来浏览和选择一个视频,一旦选择了它,我就会将它从临时存储移动到我的工作目录以供将来使用。我使用以下行来执行此操作:
[[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
【问题讨论】:
【参考方案1】:如果内存峰值与文件大小相当,则可能是将整个文件加载到内存中,如果文件大小变得非常大,这确实会导致问题。我处理这个问题的方法(复制/附加到文件时)是将文件分成小块移动,就像这样(好的旧 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;
【讨论】:
非常感谢!现在试试这个 如果您只是将现有文件从一个位置移动到另一个位置,这真的是大材小用。您可以只使用重命名()。当源和目标都在同一个卷上时,这就是 NSFileManager 应该做的,因此我的回答是。我很想知道您的应用程序的文件系统活动输出(带有回溯)。【参考方案2】:您是否正在跨不同的卷“移动”?如果是这样,那么 NSFileManager 会将文件复制到目的地并删除原始文件。此副本可能会导致您的“内存峰值”。
【讨论】:
不,我正在从临时文件(选择它们时放置视频的位置)和我的应用程序文档文件夹中移动,这是在 iphone/ipad 顺便说一句以上是关于MoveItemAtPath 的内存峰值的主要内容,如果未能解决你的问题,请参考以下文章
VM:_UITextContainerView (CALayer) - 内存峰值