Iphone NSFileManager:是否继续在后台写入磁盘?
在我的iPhone应用程序中,我使用默认的NSFileManager复制和移动一些数据。数据量可能有几MB,因此可能需要几秒钟才能完成复制。如果用户现在启动复制过程并退出应用程序,我是否可以继续以后台模式写入磁盘?如果是,怎么做?我不想启动新的复制进程,只想完成正在运行的进程 我目前使用两种方法调用:Iphone NSFileManager:是否继续在后台写入磁盘?,iphone,multithreading,cocoa-touch,background,nsfilemanager,Iphone,Multithreading,Cocoa Touch,Background,Nsfilemanager,在我的iPhone应用程序中,我使用默认的NSFileManager复制和移动一些数据。数据量可能有几MB,因此可能需要几秒钟才能完成复制。如果用户现在启动复制过程并退出应用程序,我是否可以继续以后台模式写入磁盘?如果是,怎么做?我不想启动新的复制进程,只想完成正在运行的进程 我目前使用两种方法调用: [imageData writeToFile:path atomically:YES]; 及 这两个调用都包装在另一个方法中,并通过-performSelectorInBackground:wi
[imageData writeToFile:path atomically:YES];
及
这两个调用都包装在另一个方法中,并通过-performSelectorInBackground:withObject:
在后台执行
另一个问题是,我是否可以得到任何关于写操作进展到什么程度的信息,或者至少它是否已经完成了
编辑:更多信息:
目前,我根本没有执行任何后台任务。当用户按下home按钮时,运行磁盘操作会发生什么情况?他们只是被切断,文件不完整吗?我可以在下一次开始时继续写作吗?是否取消了这些操作并删除了不完整的文件
总而言之:我正在将数据写入磁盘,我希望在写入操作期间,当用户按下home按钮时,数据保持一致。我如何做到这一点 默认情况下,当用户按下home按钮时,应用程序不会真正完成。因此,只要不花费太长时间,它就应该完成任务。如果需要很长时间,请看这个问题: 有一件事:我想你对SelectorInBackground:withObject:的性能感到困惑。 “…我继续以后台模式写入磁盘”中使用的背景与“PerformSelect in后台中的背景:withObject:”中使用的背景不相同 以前的背景: 当你的应用程序对用户不可见,但仍在运行,至少一段时间。(当用户按两次home(主页)按钮并切换到其他应用程序时) 后一种背景: 指背景线程,与主线程相对 在这种情况下,如果您使用或不使用performSelectorInBackground:withObject:它将不会影响您的应用程序是否可以在后台模式下运行。这是完全不同的事情 您可以在[fm copyItemAtPath:ToPath:error:]之后立即设置BOOL finished=YES;并将其保存在NSUserDefaults中,并在应用程序再次出现在前台时检查该标志;)
希望有帮助;) 您可能需要查看
NSOperationQueue
,文档页面为
还有两个现有的堆栈溢出问题,它们使用NSOperationQueue
解决,分别是和。两人都接受了答案
至于确定文件写入是否已完成,我在编写创建了一个非常大文件的OSX应用程序时也遇到了这个问题。我希望用户能够跟踪写入的进度。最后我使用了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];
}
}
我希望这段代码有帮助。如果有什么需要澄清的,请告诉我。Backgorund在任何一种情况下对我来说都是绝对清楚的。;)我只是添加了完整的信息。关于进展情况,我的后一个问题可能很重要。设置BOOL并不能真正解决我的问题,因为一次可能有多个磁盘操作。@Björn使用int而不是BOOL来计算未完成的操作数?请阅读:它说系统最多可以给你30秒的生命;)请参阅:beginBackgroundTaskWithExpirationHandler:method from here:在过期处理程序中,我将检查:复制了什么百分比?100%80%。在30秒内,您可以写入数百MB(如果不是更多的话)。。。你应该有足够的时间;)
- (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];