Core data 向关系插入新数据时如何更新tableView

Core data 向关系插入新数据时如何更新tableView,core-data,tableview,nsfetchedresultscontroller,relation,Core Data,Tableview,Nsfetchedresultscontroller,Relation,我使用两个实体,一个人和事件,通过一对多关系“事件”连接。在我的第一个表视图中,我有人名,在第二个表视图中,我有他们的事件类型。我可以向特定的人插入新事件,但问题是第二个表视图也不会更新。只有当我使用navigator返回到persons,并且在它再次返回事件之后,我才能看到更改 对于插入新事件,我使用以下方法: - (void) addEventControllerDidSave:(NSString *)typeData{ NSManagedObjectContext* contex

我使用两个实体,一个人和事件,通过一对多关系“事件”连接。在我的第一个表视图中,我有人名,在第二个表视图中,我有他们的事件类型。我可以向特定的人插入新事件,但问题是第二个表视图也不会更新。只有当我使用navigator返回到persons,并且在它再次返回事件之后,我才能看到更改

对于插入新事件,我使用以下方法:

- (void) addEventControllerDidSave:(NSString *)typeData{

    NSManagedObjectContext* context = [self managedObjectContext];
    Event *newEvent = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];
    [newEvent setType:typeData];
    [currentPerson addEventsObject:newEvent];

    NSError *error;
    if (![[self managedObjectContext] save:&error])
    {
        NSLog(@"Problem saving: %@", [error localizedDescription]);
    }

    [self dismissViewControllerAnimated:YES completion:nil];
}
如何定义单元格:

//create cell use relation
    NSArray *eventsArray = [[[[self currentPerson] events] objectEnumerator]allObjects];
    Event *newEvent = [eventsArray objectAtIndex:indexPath.row];
    [[cell textLabel]setText: [newEvent type]];
更新表方法:

- (void) controllerWillChangeContent:(NSFetchedResultsController *)controller{
    [[self tableView] beginUpdates];
}

- (void) controllerDidChangeContent:(NSFetchedResultsController *)controller{
    [[self tableView] endUpdates];
}

- (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:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeUpdate:
        {
            NSArray *eventsArray = [[[[self currentPerson] events] objectEnumerator]allObjects];
            Event *newEvent = [eventsArray objectAtIndex:indexPath.row];
            UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
            [[cell textLabel]setText: [newEvent type]];
            break;
        }
        case NSFetchedResultsChangeMove:
        {
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        }
        default:
            break;
    }//switch
}

- (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:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                          withRowAnimation:UITableViewRowAnimationFade];
            break;
        default:
            break;
    }
}
-(void)controllerWillChangeContent:(NSFetchedResultsController*)控制器{
[[self tableView]开始更新];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器{
[[self tableView]endUpdates];
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeObject:(id)索引路径中的一个对象:(NSIndexPath*)变更类型的indexPath:(NSFetchedResultsChangeType)类型newIndexPath:(NSIndexPath*)newIndexPath{
UITableView*tableView=[self tableView];
开关(类型){
案例NSFetchedResultsChangesInsert:
[tableView InsertRowsatindExpath:[NSArray arrayWithObject:newIndexPath]带RowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]和RowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeUpdate:
{
NSArray*eventsArray=[[[self-currentPerson]事件]对象枚举器]AllObject];
Event*newEvent=[eventsArray objectAtIndex:indexPath.row];
UITableViewCell*单元格=[tableView cellForRowAtIndexPath:indexPath];
[[cell textLabel]setText:[newEvent type]];
打破
}
案例NSFetchedResultsChangeMove:
{
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]和RowAnimation:UITableViewRowAnimationFade];
[tableView InsertRowsatindExpath:[NSArray arrayWithObject:newIndexPath]带RowAnimation:UITableViewRowAnimationFade];
打破
}
违约:
打破
}//开关
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeSection:(id)sectionInfo atIndex:(nsInteger)ChangeType的sectionIndex:(NSFetchedResultsChangeType)类型
{
开关(类型){
案例NSFetchedResultsChangesInsert:
[self.tableView insertSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
违约:
打破
}
}
我真的不知道如何正确更新tableView,我更新了第一个tableView,但第二个tableView存在我之前描述的问题(可能是因为我使用了relation?) 您还可以在git上看到我的完整项目(可能有帮助):


EventsTableController具有
fetchResultsController
属性和相应的
\u fetchResultsController
实例变量。但此FRC始终为
nil
,因为它从未在
EventsTableController
中分配和初始化

从不调用更新方法
controllerWillChangeContent
didChangeObject
controllerDidChangeContent
,因为您没有带委托的FRC

作为解决方法,您可以添加

[self.tableView reloadData];
addEventControllerDidSave
中,新条目将立即可见

但真正的解决方案是初始化并使用FRC,正如您在
NamesTableController
中所做的那样。然后,新事件将自动显示


创建一个获取当前人员所有事件的获取结果控制器如下所示(这是您从
NamesTableController
中获得的代码,已修改为在
EventsTableController
中使用):


再次谢谢你!,我把这行放在综合fetchResultsController=\u事件fetchResultsController;当然,我把NFC改成了eventsNFC。。实体和属性,但我仍然有这个问题,我做错了什么?@Dennis:NamesTableController有一个方法
-(NSFetchedResultsController*)fetchResultsController
,其中FRC是使用提取请求和排序描述符创建的。-您必须向EventsTableController添加一个类似的方法,在该方法中,您可以为事件创建FRC。这正是我所做的,正如您在“新提交”中所看到的:(简短评论)但由于某种原因,这不起作用。@Dennis:我将查看它,但不会在今晚(德国时间)之前查看它-在表视图数据源方法
numberofrowsinssection
cellforrowatinexpath
,…,中不使用FRC。。。!只是为了理解我需要在这个方法中使用FRC,因为FRC会被更新,然后我的tableView也会被更新,对吗?但当我创建新事件时,我使用以下代码:[currentPerson addEventsObject:newEvent];我的新事件对象是否保存在“事件”关系中?或者仅仅是一些知道连接到事件的关系的索引?当我创建FRC时,我需要使用哪些实体和属性?事件和类型?
-(NSFetchedResultsController *) fetchResultsController{
    if (_fetchResultsController != nil) {
        return _fetchResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"
                                              inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", self.currentPerson];
    [fetchRequest setPredicate:predicate];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:@"type" ascending:YES];
    NSArray *sortArray = [[NSArray alloc]initWithObjects:sort, nil];
    [fetchRequest setSortDescriptors:sortArray];

    _fetchResultsController = [[NSFetchedResultsController alloc]
                               initWithFetchRequest:fetchRequest
                               managedObjectContext:[self managedObjectContext]
                               sectionNameKeyPath:nil
                               cacheName:nil];

    _fetchResultsController.delegate = self;
    return _fetchResultsController;
}