Подтвердить что ты не робот

Исходный фоновой фон данных с помощью нового типа NSPrivateQueueConcurrencyType

Неужели это сейчас так просто в iOS5?

Я использовал фоновый выбор, используя этот код в приложении AppDelegate:

dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL);
dispatch_async(downloadQueue, ^{
        self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.managedObjectContext];
        [self.myDownloadClass download];
    });

dispatch_release(downloadQueue);

Мой класс загрузки выполняет NSURLConnection для извлечения некоторых данных XML, использует NSXMLParser для анализа данных, а затем обновляет сложную схему в основных данных. Я бы всегда переключился на основной поток, чтобы фактически обновить основные данные. Мессиальный код с большим количеством вызовов dispatch_sync (dispatch_get_main_queue()....

Мой новый код выглядит следующим образом:

NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:self.managedObjectContext];

[child performBlock:^{
    self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child];
    [self.myDownloadClass download];
    }];

вместе с небольшим изменением на некоторый другой код в моем AppDelegate, чтобы установить тип контекста объекта родительской модели в NSMainQueueConcurrencyType:

- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}

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

Просто помните, хотите ли вы зафиксировать свои изменения в файлах данных физического ядра, у вас есть вызов save: в родительском контексте.

Я не задавал здесь вопроса. Я публикую это, чтобы он помогал другим, потому что все, что я нашел при поиске новых методов контекста управляемого объекта iOS5, давало только подробные сведения о высоком уровне без примеров кода. И все остальные поисковые запросы по извлечению основных данных в фоновом режиме старые, иногда очень старые, и обсудите, как сделать это до iOS5.

4b9b3361

Ответ 1

Да - это действительно так легко сейчас (в iOS 5.0). Для совместимости с iOS 4 предыдущие препятствия остаются, но документация не так уж плоха при ограничении потоков. Может быть, вы должны добавить это в раздел wiki?

Ответ 2

Я пытаюсь понять, как реализован этот новый API. Моя обычная схема для многопоточных данных ядра выглядит примерно так:

Обычно в NSOperation, но упрощенном использовании dispatch_async в этом примере:

dispatch_queue_t coredata_queue; // some static queue

dispatch_async(coredata_queue, ^() {
    // get a new context for this thread, based on common persistent coordinator
    NSManagedObjectContext *context = [[MyModelSingleton model] threadedContext];

    // do something expensive

    NSError *error = nil;
    BOOL success = [context save:&error];
    if (!success) {
        // the usual.
    }

    // callback on mainthread using dispatch_get_main_queue();
});

Затем основной поток ответит обновлением пользовательского интерфейса на основе NSManagedObjectContextDidSaveNotification, чтобы объединить основной контекст.

Новый API, похоже, является оберткой вокруг этого шаблона, где контекст child выглядит так, будто он просто переносит постоянный координатор из своего родителя, чтобы создать новый контекст. И указывая NSPrivateQueueConcurrencyType на init, убедитесь, что параметр performBlock выполняется в частной очереди.

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