Как безопасно выполнить импорт файлов в фоновых потоках? Как сделать безопасные файловые операции ввода-вывода в фоновом режиме? - PullRequest
1 голос
/ 03 июня 2011

Я ищу рекомендации по решению этой сложной проблемы:

Мое приложение имеет функцию импорта / экспорта файлов в сочетании с Core Data.Это означает, что когда я импортирую файл в свое приложение, я создаю запись в Core Data и копирую этот файл в личный каталог приложения.Затем я обрабатываю файл и создаю из него несколько других для разных целей в приложении.Это тяжелые вычисления, занимающие около 0,2 секунды для каждого файла на iPhone 3G.

Это означает, что я имею дело с какими-то «транзакциями» при импорте.Все это делается с использованием одного большого FileImportOperation : NSOperation, который перебирает все файлы, которые должны быть импортированы, и выполняет тяжелую работу по импорту для каждого файла в списке.

Проблема заключается в следующем: фоновые потоки и операции NSOperations получаютубит ОС всего за наносекунду без предварительного предупреждения.Только основной поток получает до 5 секунд времени, чтобы быстро сохранить работу и выйти.

Как я могу гарантировать, что я никогда не закончу импорт файла наполовину, оставив приложение в поврежденном или поврежденном состоянии?

С моей точки зрения, злая проблема в том, что фоновые потоки (включая NSOperation) сразу же убиваются, когда пользователь выходит из приложения, без каких-либо шансов на очистку.Я попытался компенсировать это, написав управляемый объект, только если все эти файлы были созданы и успешно сохранены (помните: каждый импортированный файл дублируется и обрабатывается несколько раз по-разному для разных вещей).Но я все еще могу закончить неполный импорт, уничтожив диск пользователя.

Мое временное решение проблемы выглядит так: Объект, которому принадлежат регистры NSOperationQueue для UIApplicationWillTerminateNotification уведомление.Когда он его получает, отправляет -cancelAllOperations в очередь, которая отмечает все выполняющиеся операции как отмененные.

На данный момент я застрял.Теперь мои NSOperations помечены как отмененные, но они все еще должны завершить свой текущий внутренний цикл выполнения и остановиться.

Моя следующая идея - заставить главный поток ждать, пока все операции не будут завершены.завершено , а затем пусть -applicationWillTerminate: вернется.

Я надеюсь получить несколько советов о том, как реализовать безопасные транзакции, чтобы не оставлять приложение в поврежденном состоянии при импорте в фоновом режиме.

Ответы [ 2 ]

2 голосов
/ 03 июня 2011

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

Поиск и удаление всех файлов '* .tmp' в целевой папке. Найдите в исходной папке файл, который нужно скопировать - найден один «data.DB» Скопируйте файл в целевую папку как «data.DB.tmp» Переименуйте «data.DB.tmp» в «data.DB»

При запуске приложения найдите и удалите все файлы '* .tmp'

В сочетании с обновлением БД базовых данных на основе транзакций (т. Е. Можно откатить), может ли такой подход решить вашу проблему?

Rgds, Martin

1 голос
/ 03 июня 2011

Если вы используете iOS 4.x, вы пробовали beginBackgroundTaskWithExpirationHandler?

backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (backgroundTaskIdentifier != UIBackgroundTaskInvalid) {
            [app endBackgroundTask:backgroundTaskIdentifier];
            backgroundTaskIdentifier = UIBackgroundTaskInvalid;
        }
    });
}];
...