, знакомясь с основными данными, я обнаружил, что меня озадачил вопрос о том, как передавать различные контроллеры представлений (VC) при попытке добавить данные., добавляя объект Core Data от segue
, например, в проекте CoreDataRecipes, что яблоко обеспечивает как пример (http://developer.apple.com/library/ios/#samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html) они используют следующий подход
, когда пользователь хочет добавить рецепт в список рецептов, представленных в представлении основной таблицы и нажмет кнопку Add, мастер-контроллер таблицы (так называемый RecipeListTableViewController) создает новый управляемый объект (рецепт) следующим образом:
- (void)add:(id)sender {
// To add a new recipe, create a RecipeAddViewController. Present it as a modal view so that the user's focus is on the task of adding the recipe; wrap the controller in a navigation controller to provide a navigation bar for the Done and Save buttons (added by the RecipeAddViewController in its viewDidLoad method).
RecipeAddViewController *addController = [[RecipeAddViewController alloc] initWithNibName:@"RecipeAddView" bundle:nil];
addController.delegate = self;
Recipe *newRecipe = [NSEntityDescription insertNewObjectForEntityForName:@"Recipe" inManagedObjectContext:self.managedObjectContext];
addController.recipe = newRecipe;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addController];
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[addController release];
}
этот вновь созданный объект (Рецепт) передается в RecipeAddViewController. RecipeAddViewController имеет два метода, сохранить и отменить, следующим образом:
- (void)save {
recipe.name = nameTextField.text;
NSError *error = nil;
if (![recipe.managedObjectContext save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.delegate recipeAddViewController:self didAddRecipe:recipe];
}
- (void)cancel {
[recipe.managedObjectContext deleteObject:recipe];
NSError *error = nil;
if (![recipe.managedObjectContext save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.delegate recipeAddViewController:self didAddRecipe:nil];
}
я озадачен этим дизайнерским подходом. почему RecipeListViewController создает объект, прежде чем мы узнаем, хочет ли пользователь фактически ввести новое имя рецепта и сохранить новый объект? почему бы не передать managedObjectContext в addRecipeController и дождаться, пока пользователь не ударит, чтобы создать объект и заполнить его поля данными? это позволяет избежать необходимости удаления нового объекта, если новый рецепт для добавления не существует. или почему бы просто не передать имя рецепта (строку) назад и вперед между RecipeListViewController и RecipeAddController?
я спрашиваю, потому что я борюсь, чтобы понять, когда передавать строки между перетекает, когда передавать объекты, и когда передать managedObjectContexts ...
любое руководство высоко ценится, в том числе. любые ссылки на обсуждение проблем философии дизайна.
благодарит за ваш ответ. это кажется очень изящным и позволяет избежать того, что меня беспокоит, а именно, что прерывание процесса addRecipe может привести к тому, что в моем управляемом объектеObjectContext останется пустая запись. У меня есть еще несколько вопросов относительно подхода. во-первых, я прочитал о типах параллелизма и мне интересно, почему вы выбираете NSMainQueueConcurrencyType для контекста редактирования. во-вторых, почему NSParameterAssert (recipeForEditing); нужно? –
Обновление: когда я пытаюсь использовать подход Matthias B., я получаю следующую ошибку во время выполнения: *** Завершение приложения из-за неперехваченного исключения «NSInvalidArgumentException», причина: «Родительский NSManagedObjectContext должен использовать либо NSPrivateQueueConcurrencyType, либо NSMainQueueConcurrencyType». ... возникает вопрос, когда я объявляю исходный NSManagedObjectContext в делегате приложения, мне нужно сделать его одним из этих типов, и если да, то что лучше? –