Iphone NSFileManager:是否继续在后台写入磁盘?

Iphone NSFileManager:是否继续在后台写入磁盘?,iphone,multithreading,cocoa-touch,background,nsfilemanager,Iphone,Multithreading,Cocoa Touch,Background,Nsfilemanager,在我的iPhone应用程序中,我使用默认的NSFileManager复制和移动一些数据。数据量可能有几MB,因此可能需要几秒钟才能完成复制。如果用户现在启动复制过程并退出应用程序,我是否可以继续以后台模式写入磁盘?如果是,怎么做?我不想启动新的复制进程,只想完成正在运行的进程 我目前使用两种方法调用: [imageData writeToFile:path atomically:YES]; 及 这两个调用都包装在另一个方法中,并通过-performSelectorInBackground:wi

在我的iPhone应用程序中,我使用默认的NSFileManager复制和移动一些数据。数据量可能有几MB,因此可能需要几秒钟才能完成复制。如果用户现在启动复制过程并退出应用程序,我是否可以继续以后台模式写入磁盘?如果是,怎么做?我不想启动新的复制进程,只想完成正在运行的进程

我目前使用两种方法调用:

[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];