Как Иметь дело с Временными экземплярами NSManagedObject?

Я должен создать NSManagedObject экземпляры, сделайте некоторый материал с ними и затем повредите их или хранилище к sqlite дб. Проблема, я не могу создать экземпляры NSManagedObject не связанный с NSManagedObjectContext и это означает, что я должен разрешить так или иначе после того, как я решаю, что мне не нужны некоторые объекты в моем дб.

Для контакта с ним я создал хранилище в оперативной памяти с помощью того же координатора, и я помещаю временные объекты туда при помощи assignObject:toPersistentStore. Теперь, как я удостоверяюсь, чтобы эти временные объекты не добирались до данных, которые я выбираю от общего до обоих контекстов хранилищ? Или я должен создать отдельные контексты для такой задачи?


UPD:

Теперь я думаю о создании отдельного контекста для хранилища в оперативной памяти. Как я перемещаю объекты от одного контекста до другого? Просто с помощью [контекст insertObject:]? Это будет работать хорошо в этой установке? Если я вставляю один объект от графика объектов, целый график также становится вставленным в контекст?

85
задан Andriy 6 June 2016 в 11:03
поделиться

2 ответа

ПРИМЕЧАНИЕ: Этот ответ очень старый. См. Комментарии для полной истории. С тех пор моя рекомендация изменилась, и я больше не рекомендую использовать несвязанные экземпляры NSManagedObject . Моя текущая рекомендация - использовать временные дочерние экземпляры NSManagedObjectContext .

Исходный ответ

Самый простой способ сделать это - создать экземпляры NSManagedObject без связанного NSManagedObjectContext .

NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:myMOC];
NSManagedObject *unassociatedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

Затем, когда вы захотите его сохранить:

[myMOC insertObject:unassociatedObject];
NSError *error = nil;
if (![myMoc save:&error]) {
  //Respond to the error
}
144
ответ дан 24 November 2019 в 08:12
поделиться

Правильный способ добиться такого рода вещей - использовать новый контекст управляемого объекта. Вы создаете контекст управляемого объекта с тем же постоянным хранилищем:

NSManagedObjectContext *tempContext = [[[NSManagedObjectContext alloc] init] autorelease];
[tempContext setPersistentStore:[originalContext persistentStore]];

Затем вы добавляете новые объекты, изменяете их и т. Д.

Когда приходит время сохранять, вам нужно вызвать [tempContext save: ...] в tempContext и обработайте уведомление о сохранении, чтобы объединить его с исходным контекстом. Чтобы отбросить объекты, просто отпустите этот временный контекст и забудьте о нем.

Таким образом, когда вы сохраняете временный контекст, изменения сохраняются в хранилище, и вам просто нужно вернуть эти изменения обратно в ваш основной контекст:

/* Called when the temp context is saved */
- (void)tempContextSaved:(NSNotification *)notification {
    /* Merge the changes into the original managed object context */
    [originalContext mergeChangesFromContextDidSaveNotification:notification];
}

// Here's where we do the save itself

// Add the notification handler
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(tempContextSaved:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:tempContext];

// Save
[tempContext save:NULL];
// Remove the handler again
[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:NSManagedObjectContextDidSaveNotification
                                              object:tempContext];

Таким же образом вы должны обрабатывать многопоточные операции с основными данными . Один контекст на поток.

Если вам нужно получить доступ к существующим объектам из этого временного контекста (для добавления отношений и т. Д.), Вам нужно использовать идентификатор объекта, чтобы получить новый экземпляр, например:

NSManagedObject *objectInOriginalContext = ...;
NSManagedObject *objectInTemporaryContext = [tempContext objectWithID:[objectInOriginalContext objectID]];

Если вы попытаетесь использовать NSManagedObject в неправильном контексте вы получите исключения при сохранении.

9
ответ дан 24 November 2019 в 08:12
поделиться