iOS5.1: синхронизация задач (ожидание завершения) - PullRequest
5 голосов
/ 01 апреля 2012

У меня есть основная проблема синхронизации openWithCompletionHandler: (UIManagedDocument) с основными действиями.

Ситуация: у меня есть одноэлементный класс, управляющий общим UIManagedDocument.Этот класс предоставляет один метод, который должен доставить документ в нормальном состоянии (т. Е. Создает или открывает его, независимо от того, что необходимо).Но поскольку openWithCompletionHandler: выполняет свою основную работу асинхронно в фоновом режиме, моя программа должна подождать с настройкой fetchedResultsController, пока документ действительно не откроется.Метод «viewWillAppear» (в настоящее время) не выдает полезных выходных данных, когда база данных не готова.Ожидание было бы хорошо для меня, но получение уведомления, вероятно, было бы лучшим способом.Может быть, viewWillAppear не подходит для setupFetchedResultsController, потому что он не вызывается в цикле выполнения.

Существует ли стандартный шаблон для достижения этой цели?

Немного больше фона (не так важно, я полагаю) Я работаю над небольшим приложением iOS 5.1, включающим CoreData UIManagedDocument.Я напоминал пример из урока 14 из Стэнфордского курса прошлой осенью в iTunes-U.Все работало нормально, пока я не попытался отделить обработку UIManagedDocument от класса UITableViewController в отдельный класс, обрабатывающий мой документ.В исходной версии FetchedResultsController был установлен в обработчике завершения.

1 Ответ

3 голосов
/ 27 апреля 2012

Я предлагаю следовать Отличному сообщению Джастина Дрисколла о Базовых данных с одним общим UIManagedDocument .

. Вы найдете полную запись в синглтоне UIManagedDocument ипример по executeWithDocument.Ваш установочный код fetchedResultsController должен действительно находиться в блоке executeWithDocument: ^ {}.

Также обратите внимание, что openWithCompletionHandler не является потокобезопасным - одновременные вызовы executeWithDocument при открытии документа вызывают сбой.Для меня решение было нетривиальным (и довольно специфичным для приложения), поэтому, если вы столкнетесь с той же проблемой, я предлагаю вам изучить UIDocumentStateChangedNotification , который уведомляет об изменениях состояния документа и может быть точкой синхронизации для нескольких пользователей.средства для открытия документов.

Небольшой фрагмент, если вам интересно,

Сначала в инициализации MYDocumentHandler, установите дополнительное уведомление в конце:

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(documentStateDidChange:)
                                                 name:UIDocumentStateChangedNotification
                                               object:self.document];

Затем в executeWithDocument, @synchronized(self.document) в критических разделах открытия / создания, чтобы убедиться, что только один поток заходит одновременно, и блокировать дальнейшие потоки до тех пор, пока открытие / создание завершится успешно.

Наконец добавьте следующую функцию:

- (void)documentStateDidChange:(NSNotification *)notification
{
    if (self.document.documentState == UIDocumentStateNormal)
        @synchronized (self.document) {
            ... unblock other document openers ...
        }
}

Что касается блоковых / разблокирующих потоков, YMMV.Я использовал dispatch_semaphore_t вместе с некоторыми dispatch_queues, чтобы удовлетворить специфичные для приложения требования.Ваш случай может быть таким же простым, как ожидание завершения или отбрасывание других потоков.

...