NSFileManager: Продолжить запись на диск в фоновом режиме? - PullRequest
4 голосов
/ 03 января 2011

в своем приложении для iPhone я использую NSFileManager по умолчанию для копирования и перемещения некоторых данных.Объем данных может составлять несколько МБ, поэтому завершение копирования может занять несколько секунд.Если пользователь теперь запускает процесс копирования и выходит из приложения, могу ли я продолжить запись на диск в фоновом режиме?Если так, то как?Я не хочу начинать новый процесс копирования, а только заканчиваю запущенный.

В настоящее время я использую два вида вызовов методов:

[imageData writeToFile:path atomically:YES];

и

[fm copyItemAtPath:sourcePath toPath:destinationPath error:&error];

Оба вызова заключены в другой метод и выполняются в фоновом режиме с помощью -performSelectorInBackground:withObject:.

Другой вопрос: могу ли я получить какую-либо информацию о том, как далеко продвинулась операция записи, или, по крайней мере, если она уже закончилась?не выполнял никаких фоновых задач вообще.Что происходит с выполнением операций с диском, когда пользователь нажимает кнопку «Домой»?Они просто обрезаны и файл неполон?Могу ли я продолжить писать при следующем запуске?Отменены ли они и удален ли неполный файл?

Подводя итог: я записываю данные на диск и хочу, чтобы они оставались согласованными, когда пользователь нажимает кнопку home во время операции записи.Как мне этого добиться?

Ответы [ 2 ]

4 голосов
/ 25 января 2011

Вы можете посмотреть NSOperationQueue, страница документации здесь .

Также есть два существующих вопроса переполнения стека, в которых используются 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];

Надеюсь, этот код поможет. Дайте мне знать, если что-то нужно уточнить.

4 голосов
/ 03 января 2011

По умолчанию ваше приложение не завершает работу, когда пользователь нажимает кнопку «Домой».Следовательно, он должен завершить эту задачу, так как долго это не займет слишком много времени.Если это занимает много времени, пожалуйста, взгляните на этот вопрос: Как реализовать завершение Задачи

Одна вещь: я думаю, вы не понимаете, что действительно делает executeSelectorInBackground: withObject :. фон , используемый в "... я продолжаю запись на диск в фон режим" и фон в "executeSelectorIn Фон : withObject: "это не тот же фон

Прежний фон: Когда приложение становится невидимым для пользователя, но все еще работает,по крайней мере, какое-то время.(Когда пользователь дважды нажимает кнопку «Домой» и переключается на другое приложение)

Последний фон: Указывает на фоновый поток, противоположный основному потоку.

В этом случае, если вы используете или не используете executeSelectorInBackground: withObject: это не повлияет на то, сможет ли ваше приложение сделать это в фоновом режиме или нет.Это совершенно разные вещи

Вы можете установить BOOL Finished = YES сразу после [fm copyItemAtPath: ToPath: error:];и сохраните его в NSUserDefaults и проверьте этот флаг, когда ваше приложение снова выйдет на передний план;)

Надеюсь, это поможет;)

...