NSManagedObject: создать в отдельном потоке - PullRequest
5 голосов
/ 07 июля 2011

Я понимаю, что Core Data не является поточно-ориентированным и что NSManagedObjectContext и NSManagedObjects, связанные с контекстом, не могут быть переданы из потока в поток.

Вопрос:

Однако, если у меня есть NSManagedObjectContextв моем основном потоке я могу создать объект NSManagedObject в фоновом потоке (БЕЗ присоединения его к любому контексту - то есть просто вызвать alloc / init для NSManagedObject), затем передать этот NSManagedObject обратно в основной поток и добавить его вконтекст оттуда?Я просмотрел документы по параллелизму Core Data, но не могу найти ничего, что говорит, что этот шаблон использования в порядке.

Контекст:

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

Если я не могу создатьУправляемый объект в фоновом потоке, затем мне нужно будет создать словарь, передать словарь в основной поток, прочитать ключи, создать управляемый объект из этих значений и т. д. Кажется, проще создать управляемый объект в фоновом потоке, если это возможно.

1 Ответ

7 голосов
/ 07 июля 2011

Лучший подход - иметь контекст для потока. Таким образом, каждая нить будет иметь свою собственную блокнот для игры. Затем, когда вы завершите фоновый поток, скажите своему основному потоку обновить его представление или представление пользовательского интерфейса или то, как каждый из вас представляет свои данные.

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

Так, например, в вашем основном методе в вашей NSOperation, вы можете сделать это:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self
       selector:@selector(mergeChanges:)
           name:NSManagedObjectContextDidSaveNotification
         object:context];

mergeChanges будет закрытым методом в вашем экземпляре NSOperation.

пример изменений слияния

- (void)mergeChanges:(NSNotification *)notification
{
    ApplicationController *appController = [[NSApplication sharedApplication] delegate];
    NSManagedObjectContext *mainContext = [appController managedObjectContext];

    // Merge changes into the main context on the main thread
    [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                  withObject:notification
                               waitUntilDone:YES];  
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...