Сохранение основных данных в потоке - PullRequest
0 голосов
/ 30 ноября 2011

Я занимаюсь разработкой клиент-серверного приложения на iPad. Мне нужно сохранить большое количество данных, которые сервер отправляет мне. он посылает мне длинную строку, и мне нужно разбить ее на небольшие записи и сохранить в основных данных. он посылает мне всего около 20 сообщений, и каждое сообщение содержит около 100 записей.

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

Вопрос. Могу ли я получить сообщение с сервера и разбить данные и сохранить их в потоках? я продолжаю получать ошибку sigbart, когда контекст сохраняется. Я проверил основные данные, они сохраняют около 4 записей, прежде чем нажать на эту ошибку.

Может ли несколько потоков одновременно получать доступ к основным данным?

Извините, я действительно потерян. попробовал Magical Records с открытым исходным кодом, но он продолжает иметь ошибки.

Ответы [ 2 ]

0 голосов
/ 31 августа 2012

Поскольку для базовых данных требуется один контекст управляемого объекта на поток, возможным решением было бы отслеживать контекст для каждого потока в глобальном менеджере, а затем отслеживать уведомления о сохранении и распространять на все потоки:

Предполагая:

@property (nonatomic, strong) NSDictionary* threadsDictionary;

Вот как получить управляемый объект (для потока):

- (NSManagedObjectContext *) managedObjectContextForThread {

// Per thread, give one back
NSString* threadName = [NSString stringWithFormat:@"%d",[NSThread currentThread].hash];

NSManagedObjectContext * existingContext = [self.threadsDictionary objectForKey:threadName];
if (existingContext==nil){
    existingContext = [[NSManagedObjectContext alloc] init];
    [existingContext setPersistentStoreCoordinator: [self persistentStoreCoordinator]];
    [self.threadsDictionary setValue:existingContext forKey:threadName];
}

return existingContext;

}

В какой-то момент в методе init вашего глобального менеджера (я использовалsingleton):

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backgroundContextDidSave:)                                                    name:NSManagedObjectContextDidSaveNotification                                                   object:nil];

Затем, чтобы получать уведомления о сохранении и распространяться на все другие объекты управляемого контекста:

- (void)backgroundContextDidSave:(NSNotification *)notification {
    /* Make sure we're on the main thread when updating the main context */
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
                               withObject:notification
                            waitUntilDone:NO];
        return;
    }

    /* merge in the changes to the main context */
    for (NSManagedObjectContext* context in [self.threadsDictionary allValues]){
            [context mergeChangesFromContextDidSaveNotification:notification];
    }
}

(некоторые другие методы были удалены для ясности)

0 голосов
/ 30 ноября 2011

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

Это позволит вам сохранить в фоновом режиме, используя Core Data.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...