防止核心数据创建空对象

时间:2013-02-06 20:04:29

标签: objective-c uitableview core-data ios6 nsmanagedobjectcontext

这是我用来创建新对象的代码。问题是,如果我选择不保存新对象,它会创建一个空的tableview单元格。我该如何防止这种情况发生?

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"Add"]) {
        NSLog(@"Setting PersonsTVC as a delegate of PersonDetailTVC");
        StepDetailView *personDetailTVC = segue.destinationViewController;
        personDetailTVC.delegate = self;
        personDetailTVC.title = @"Add New Step";
        NSLog(@"Creating a new person and passing it to PersonDetailTVC");
        Step *newPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Step"
                                                        inManagedObjectContext:self.managedObjectContext];

        personDetailTVC.person = newPerson;
    }
    else {
        NSLog(@"Unidentified Segue Attempted!");
    }
}

到目前为止我尝试过的是在personDetailTVC.person = newPerson;

之后插入以下代码
if (newPerson.name == nil) {
    [self.managedObjectContext deleteObject:newPerson];
    [self.managedObjectContext save:nil];

    [self performFetch];
    [self.tableView reloadData];
}

但它不是一个好的解决方案,因为它会导致应用程序崩溃,因为tableview单元格不会被删除,只有对象才会被删除。 我认为我可以做的是,如果对象为null,则自动删除第一个tableview单元格,但我还没有找到方法。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我正在猜测我认为这里发生了什么。如果错误,请更正我的任何假设。

  • 你有一个UITableView
  • 使用CoreData中的数据填充单元格。
  • 你正在通过NSFetchedResultsController填充它
  • segue是一个PersonDetailVC,允许用户输入新的托管对象的数据?

当你'insertNewObjectForEntity:'创建一个新的空白managedObject并将其插入到Core Data中时,会发生什么。 NSFetchedResultsController收到更改通知,新单元格插入UITableView。 NSFetchedResultsController获取更改,并添加一个空白单元格。

无论您是否保存上下文,它都已存在于您的核心数据存储中。 “保存”只是确保更改反映在核心数据的持久存储(sqlite或plist)中。核心数据存在于内存中,sqlite持久存储仅用于持久化。

在用户输入数据之前,解决方案不会插入到核心数据中。你不应该在segue中进行核心数据插入。

解决方案: - 在没有创建新对象的情况下搜索PersonDetailVC。 - 用户完成数据输入后,用户按“保存”或“完成” - 从PersonDetailVC弹回时,使用填充的字段将新的managedObject插入Core Data。 - NSFetchedResultsController将接收更改并适当地修改UITableView。

注意:如果您使用的是NSFetchedResultsController,则不需要[self.tableview reloadData]。在合并所有更改后,fetchedresultscontroller会为您调用它。