美好的一天,大家!
我有一个UITableView。我需要添加一些对象(有一些属性,在这种情况下,我至少需要名称),当我在导航栏中点击“+”时,新的UIViewController以模态方式呈现,而在viewDidLoad我调用此方法,设置默认名称它:
- (void)createManagedObject {
NSManagedObjectContext *context = [[DVCoreDataManager sharedManager] managedObjectContext];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"DVObject" inManagedObjectContext:context];
[newManagedObject setValue:@"new object" forKey:@"name"];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"%@", [error localizedDescription]);
}
self.currentObjectID = newManagedObject.objectID;
}
在UITextField中输入名称后,我点击“保存”按钮并调用该方法,我需要更新对象的名称:
- (IBAction)actionSaveTraining:(UIBarButtonItem *)sender {
NSManagedObjectContext *context = [[DVCoreDataManager sharedManager] managedObjectContext];
NSManagedObject *newManagedObject = [context existingObjectWithID:self.currentObjectID error:nil];
[newManagedObject setValue:self.nameTextField.text forKey:@"name"];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"%@", [error localizedDescription]);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
此时应用程序因错误而崩溃:
***由于未捕获的异常'NSInternalInconsistencyException'而终止应用,原因:'无效更新:无效 第0节中的行数。包含在中的行数 更新后的现有部分(7)必须等于数量 更新前的该部分中包含的行(7),加号或减号 从该部分插入或删除的行数(插入0, 删除1)加上或减去移入或移出的行数 该部分(0移入,0移出)。'
我已经实现了NSFetchedResultsControllerDelegate方法。 controllerDidChangeContent:在createManagedObject方法之后调用,但 controllerWillChangeContext:从未被调用,我无法理解为什么。
- (void)controllerWillChangeContext:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeMove:
break;
case NSFetchedResultsChangeUpdate:
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch (type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
default:
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
如何解决此错误?也许有更好的方法来做我需要的事情? (在创建时设置默认名称,保存时,从uitextfield设置名称)
答案 0 :(得分:1)
您输入的controllerWillChangeContent
方法名称不正确:最后一个字应为内容而非上下文:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
答案 1 :(得分:0)
关于更好的方法的评论,我看到你有一个刚刚创建的对象managedObjectID
的属性。您是否有任何理由不仅拥有托管对象本身的属性?创建新对象后,您将其分配给您的本地属性。然后当你更新它时,你只需要调用
[self.newObject setValue:self.nameTextField.text forKey:@"name"];
然后像你已经做的那样保存(只要你在方法[[DVCoreDataManager sharedManager] managedObjectContext]
中提供的上下文是NSMainQueueConcurrencyType
类型。如果它是一个背景上下文,你需要包装两个那些-performBlock:
或performBlockAndWait:
)。
这也假设从呈现的viewController中获取的结果控制器使用与新对象viewController相同的NSManagedObjectContext
。