在我的iPhone应用程序中,我使用默认的NSFileManager来复制和移动一些数据。数据量可能是几MB,因此完成复制可能需要几秒钟。如果用户现在启动复制过程并退出应用程序,是否可以继续以后台模式写入磁盘?如果是这样,怎么样?我不想开始新的复制过程,但只完成正在运行的过程。
我目前正在使用两种方法调用:
[imageData writeToFile:path atomically:YES];
和
[fm copyItemAtPath:sourcePath toPath:destinationPath error:&error];
两个调用都包含在另一个方法中,并通过-performSelectorInBackground:withObject:
在后台执行。
另一个问题是,我是否可以获得有关写入操作进展程度的信息,或者至少是否已经完成?
编辑:更多信息: 目前,我根本没有执行任何后台任务。当用户按下主页按钮时,运行磁盘操作会发生什么?他们刚刚被切断,文件是不完整的?我可以在下次开始时继续写作吗?它们被取消并且删除了不完整的文件吗?
总结一下:我正在将数据写入磁盘,并且当用户在写入操作期间按下主页按钮时,我希望它保持一致。我该如何实现这一目标?
答案 0 :(得分:4)
默认情况下,当用户按下主页按钮时,应用程序无法完成。因此它应该完成那项任务,只要不花太长时间。如果需要很长时间,请查看以下问题:How to implement Task completion
有一件事:我认为你对performSelectorInBackground:withObject:确实存在困惑。 后台用于“...我继续以 后台 模式写入磁盘”和后台中的“ performSelectorIn 背景 :withObject:“背景不一样
前一个背景: 当你的应用程序对用户不可见但仍在运行时,至少会持续一段时间。 (当用户按两次主页按钮并切换到另一个应用程序时)
后一种背景: 引用后台线程,它与主线程相反。
在这种情况下,如果您使用或不使用performSelectorInBackground:withObject:它将不会影响您的应用程序是否可以执行后台模式。这些是完全不同的东西
你可以在[fm copyItemAtPath:ToPath:error:]之后立即设置BOOL finished = YES;并将其保存在NSUserDefaults中并在应用程序再次到达前台时检查该标志;)
希望它有所帮助;)
答案 1 :(得分:4)
您可能需要查看NSOperationQueue
,文档页面为here。
此外,还有两个现有的Stack Overflow问题使用here和here NSOperationQueue
来解决。两人都接受了答案。
至于确定文件写入是否已完成,我在写一个创建一个非常大的文件的OS X应用程序时也遇到了这个问题。我希望用户能够跟踪写入的进度。我最终使用NSTimer
和UIProgressBar
基本上,您需要确定文件的(预期)总大小。然后,当您编写文件时,您应该使用另一种方法(在下面的代码中我有checkFileWritingProgress
),您可以使用NSTimer
定期调用。根据预期的文件总大小检查当前进度,并相应地更新UIProgressBar
。
我提供了一些代码来帮助您入门。
- (void)checkFileWritingProgress:(NSTimer *)someTimer {
fileAttributes = [fileManager attributesOfItemAtPath:[NSString stringWithFormat:@"%@.data",saveLocation] error:nil];
currentFileSize = [fileAttributes fileSize]; // instance variable
if(currentFileSize < maxFileSize) { // maxFileSize is instance variable
[progressBar setDoubleValue:(((double)currentFileSize/(double)maxFileSize)*100)];
// progressWindows OS X only... not on iOS
//[progressWindow setTitle:[NSString stringWithFormat:@"Writing... | %.0f%%",(((double)currentFileSize/(double)maxFileSize)*100)]];
}
else {
[progressBar setDoubleValue:100.0];
}
}
计时器......
NSTimer *timer = [[NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:@selector(checkFileWritingProgress:)
userInfo:nil
repeats:YES] retain];
//(linked to timer... this is the
// CORRECT way to use a determinate progress bar)
[progressBar setIndeterminate:NO];
[progressBar setDoubleValue:0.0];
[progressBar displayIfNeeded];
我希望此代码有所帮助。如果有任何事情需要澄清,请告诉我。