У меня случайные сбои с основными данными из-за параллелизма и многопоточности. Я знаю, что данные ядра не являются потокобезопасными. Я также нашел пару других ответов о том, как создать ThreadedDataService и создать отдельный контекст для каждого потока.
Это слишком много для меня, чтобы проглотить в данный момент, поэтому я пытаюсь найти более легкий выход.
Решение, которое я сейчас пробую, простое: сохранение данных через основной поток. Однако теперь возникает новая проблема: deadlock . Приложение перестает отвечать на запросы, потому что за каждой моей вставкой нового NSManagedObject следует вызов для сохранения. (это мое лучшее предположение).
Читая документацию App Delegate, я заметил, что она советует мне сохранять контекст в applicationWillTerminate.
У меня такой вопрос: Для длительной операции, которая вставляет новые события каждую минуту, и пользователю не требуется видеть обновления, распространяемые сразу на все контроллеры, когда мне пора сохранить контекст
У меня такое ощущение, что сохранение контекста для каждой записи может быть излишним?
-(void)insertNewEvent
{
// Create a new instance of the entity managed by the fetched results controller.
NSManagedObjectContext *context = [self.fetchedResultsController.managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsControllerfetchRequest] entity];
Event*newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
//use accessor methods to set default values
// Save the context. > IS THIS REALLY NEEDED HERE?
NSError *error = nil;
if (![context save:&error])
{
}else
{
if(newManagedObject!=nil)
{
currentState= newManagedObject;
[currentRecord addEvent:newManagedObject];
//Is this call needed?
[self saveApplicationRecords];
}
}
}
У меня есть методы, подобные этим, определенные для всех моих управляемых объектов, достаточно ли этого, если я вызываю такой метод в главном потоке каждые 10-15 минут, чтобы сохранять ожидающие изменения, а не делать это после каждой вставки записи?
-(void)saveApplicationRecords
{
NSLog(@"saveApplicationRecords");
NSManagedObjectContext *context = [self.applicationRecordsController.managedObjectContext];
// Save the context.
NSError *error = nil;
if (![context save:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
Дополнительный вопрос после прочтения ответа macbirdie: допустим ли этот метод в основных данных?
-(Event*)insertAndReturnNewEventWithDate:(NSDate*)date_ type:(int)type
{
NSManagedObjectContext *context = [self.dreamEventsController managedObjectContext];
NSEntityDescription *entity = [[self.dreamEventsController fetchRequest] entity];
DreamEvent *newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
//handle properties
NSError *error = nil;
if (![context save:&error])
{
return nil;
}else
{
return newManagedObject ;
}
}
Спасибо!