Я борюсь с каким-то странным поведением в Core Data. У меня довольно стандартная настройка, используя пример CoreDataBook: у меня есть RootView, который использует NSFetchedResultsController для отображения списка элементов. Элемент имеет несколько атрибутов и отношений с другими объектами. У меня есть DetailView, который я использую, чтобы создать новый Item, а также отредактировать существующий элемент, который я представляю модально. В DetailView: viewDidLoad, я создаю новый managedObjectContext, в котором я хочу сделать все изменения ... если пользователь нажимает Save, я сохраняю этот контекст и объединяя изменения; в противном случае, если пользователь нажимает на отмену, все эти изменения просто исчезают.Основные данные - отношения идут ноль неожиданно
«Добавить новый элемент» часть этого прекрасно работает, но когда я выбираю строку, чтобы вывести тот же DetailView, что и существующий элемент, одно из отношений (которое отлично видно в RootView в отладчике) внезапно становится nil, когда он представлен в DetailView. Вот код для отображения DetailView в didSelectRowAtIndexPath UITableView в:
Item *managedObject = (Item *)[self.fetchedResultsController objectAtIndexPath:indexPath];
DetailView *childController = [[DetailView alloc] initWithNibName:@"DetailView" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:childController];
childController.existingItem = managedObject;
// ** Item's relationship to Title is not nil at this point
[self presentModalViewController:navController animated:YES];
// ** Item's relationship Title is now nil
[childController release];
[navController release];
Там нет ничего лишнего неординарного в контроллере DetailView, что бы привести к этому. На самом деле, у него даже нет шансов нанести какой-либо ущерб ... как только он начнется, существующее отношение Item.title уже равно нулю. [existingItem является сохраненным свойством DetailView]
Любая идея, где я должен начать изучать это? За последние несколько часов меня сводило с ума. Вот код в DetailView viewDidLoad, но отношения ноль еще до того, как это называется:
// Create a new managed object context
NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
self.addEditContext = addingContext;
[addingContext release];
[self.addEditContext setPersistentStoreCoordinator:[[appDelegate managedObjectContext] persistentStoreCoordinator]];
if (!self.existingItem) {
self.existingItem = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext: self.addEditContext];
}else{
self.existingItem = (Item *)[self.addEditContext objectWithID:[self.existingItem objectID]];
}
Названное зависимость устанавливается путем выбора из некоторого списка:
self.existingItem.title = selectedTitle;
В экономии: метод, за исключением I addEditContext и объединить изменения с AppDelegate контекста:
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
[dnc addObserver:self selector:@selector(addControllerContextDidSave:) name:NSManagedObjectContextDidSaveNotification object: self.addEditContext];
// Save the context.
NSError *error = nil;
if (![self.addEditContext save:&error]){
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
[dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.addEditContext];
self.addEditContext = nil;
В addControllerContextDidSave:
- (void)addControllerContextDidSave:(NSNotification*)saveNotification {
id appDelegate = [[UIApplication sharedApplication] delegate];
// Merging changes causes the fetched results controller to update its results
[[appDelegate managedObjectContext] mergeChangesFromContextDidSaveNotification:saveNotification];
}
Таким образом, файл save: stuff отлично подходит для нового элемента, но когда этот элемент установлен на существующий и снова загружен, self.existingItem.title равен нулю. И это ничто из того, что оно представлено в контроллере представления (хотя это не ноль, прежде чем он будет представлен). Таким образом, в основном контексте он отлично загружает отношения с Item и it title, но затем название внезапно исчезает, когда оно представлено в presentModalViewController: navController.
Действительно странно. Если кто-то может пролить свет на это, это будет действительно оценено.
Обновление: еще одна вещь, которую следует упомянуть, заключается в том, что название определенно сохраняется в persistentStore. Каждый раз, когда я закрываю и перезагружаю приложение, RootView показывает установленное отношение названия. Как только я выбираю строку, отношение становится нулевым.
Спасибо за ваши комментарии. existingItem определенно задан как @property (сохранить, неатомный) Item * existingItem, так что это не так. Причина, по которой я создал другой контекст, заключается в том, что я хочу, чтобы пользователь сделал кучу изменений в existingItem (или при добавлении нового), но есть кнопка отмены на странице, чтобы откатить все в случае, если пользователь решит. Я чувствовал, что самый простой способ сделать это - создать отдельный контекст, чтобы изменения не влияли на контекст основного потока. Есть лучший способ сделать это? –
Я также попытался использовать NSUndoManager для отслеживания и отката изменений вместо нескольких контекстов. Но у него тоже есть та же проблема. Взаимодействие «title» отлично в файле didSelectRowAtIndexPath RootView до момента, когда он вызывает [self presentModalViewController: navController animated: YES], а затем он просто исчезает как из RootView, так и из DetailView. Теперь с UndoManager, когда изменения отменены, заголовок восстанавливается в представлении, но он все еще не отображается в DetailView (хотя все в одном контексте). Означает ли это, что я могу ошибаться? –
Кроме того, я добавил еще одно соотношение (1 к 1), которое отлично работает и отображается в DetailView. Соотношение заголовков много-к-одному (от элементов к заголовку ... так что заголовок может быть связан с несколькими элементами, но каждый элемент имеет один заголовок). –