Ios NSFetchedResultsController/NSFetchedResultsController委托双/三重/…;插入部分

Ios NSFetchedResultsController/NSFetchedResultsController委托双/三重/…;插入部分,ios,core-data,Ios,Core Data,我这里有一个(至少对我来说)搁浅的问题: 我有一个UITableViewController,它有一个NSFetchedResultsController来处理要显示的数据 应该显示的数据来自服务器,为了方便起见,可以说这是一种聊天 简化模型可描述如下 --------------- ----------------- ----------------- | MainTopic | | Thread |

我这里有一个(至少对我来说)搁浅的问题:

我有一个UITableViewController,它有一个NSFetchedResultsController来处理要显示的数据

应该显示的数据来自服务器,为了方便起见,可以说这是一种聊天

简化模型可描述如下

---------------           -----------------           -----------------
|  MainTopic  |           |     Thread    |           |    Message    |
---------------           -----------------           -----------------
| topicID (E) |           | threadID (E)  |           |   msgID   (E) |
| name (E)    |           | name (E)      |           |   msgText (E) |
---------------           -----------------           |   msgDate (E) |           
| threads (R) | <------>> | mainTopic (R) |           -----------------
---------------           | messages (R)  | <------>> |   thread (R)  |
                          -----------------           -----------------
现在有人将消息(消息3)写入第一个线程,从服务器获取数据(用户保留在表视图中)。现在,表视图如下所示

______________________________________
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 3                          |
|____________________________________|
| Thread: Second thread              |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|
如您所见,第一个线程的节标题出现两次

如果UITableViewController将被保留并再次打开(弹出并将新实例推送到navigationController),则表看起来很好:

______________________________________
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
| Message 3                          |
|____________________________________|
| Thread: Second thread              |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|
因此,我认为错误一定在NSFetchedResultsControllerDelegate方法中的某个地方,但因为它们看起来“正常”

#pragma标记-NSFetchedResultsControllerDelegate方法
-(void)controllerWillChangeContent:(NSFetchedResultsController*)控制器
{
[[self tableView]开始更新];
}
-(void)控制器:(NSFetchedResultsController*)控制器
didChangeSection:(id)sectionInfo
atIndex:(整数)sectionIndex
forChangeType:(NSFetchedResultsChangeType)类型
{
NSIndexSet*indexSet=[NSIndexSet indexSetWithIndex:sectionIndex];
开关(类型){
案例NSFetchedResultsChangesInsert:
[[self tableView]insertSections:indexSet
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[[self tableView]删除节:索引集
withRowAnimation:UITableViewRowAnimationFade];
打破
违约:
打破
}
}
-(void)控制器:(NSFetchedResultsController*)控制器
didChangeObject:(id)一个对象
atIndexPath:(nsindepath*)indepath
forChangeType:(NSFetchedResultsChangeType)类型
newindepath:(nsindepath*)newindepath
{
NSArray*oldArray=nil;
if(indexath){
oldArray=[NSArray arrayWithObject:indexPath];
}
NSArray*newArray=nil;
if(newIndexPath){
newArray=[NSArray arrayWithObject:newIndexPath];
}
开关(类型){
案例NSFetchedResultsChangesInsert:
[[self tableView]insertRowsAtIndexPaths:newArray
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[[self tableView]删除RowsatindExpaths:oldArray
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeUpdate:
{
UITableViewCell*单元格=nil;
Message*Message=nil;
cell=[[self tableView]cellforrowatinexpath:indexPath];
message=[[self-fetchedResultsController]objectAtIndexPath:indexPath];
[单元格设置消息文本:[消息msgText]];
}
打破
案例NSFetchedResultsChangeMove:
[[self tableView]insertRowsAtIndexPaths:newArray
withRowAnimation:UITableViewRowAnimationFade];
[[self tableView]删除RowsatindExpaths:oldArray
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器
{
[[self tableView]endUpdates];
}

那么,有没有人给我一个提示,问题可能在哪里?

您能展示一下创建获取结果控制器的代码吗?我认为错误不在frc委托方法中。如果调用了“didChangeSection:”方法,则该表只是在执行它被告知要执行的操作(即,添加一个节)。“didChangeSection:”之所以被调用,是因为控制器“相信”正在添加一个新的分区,所以在我看来,您的问题出在其他地方。当你找到答案时,让我们知道问题出在哪里。
______________________________________
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
| Message 3                          |
|____________________________________|
| Thread: Second thread              |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|
#pragma mark - NSFetchedResultsControllerDelegate methods

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

- (void)controller:(NSFetchedResultsController *)controller
  didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex
     forChangeType:(NSFetchedResultsChangeType)type
{

    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:sectionIndex];
    switch (type) {
        case NSFetchedResultsChangeInsert:
            [[self tableView] insertSections:indexSet
                            withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [[self tableView] deleteSections:indexSet
                            withRowAnimation:UITableViewRowAnimationFade];
            break;
        default:
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    NSArray * oldArray = nil;
    if(indexPath) {
        oldArray = [NSArray arrayWithObject:indexPath];
    }
    NSArray * newArray = nil;
    if(newIndexPath) {
        newArray = [NSArray arrayWithObject:newIndexPath];
    }

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [[self tableView] insertRowsAtIndexPaths:newArray
                                    withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [[self tableView] deleteRowsAtIndexPaths:oldArray
                                    withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeUpdate:
        {
            UITableViewCell * cell = nil;
            Message * message = nil;
            cell = [[self tableView] cellForRowAtIndexPath:indexPath];
            message = [[self fetchedResultsController] objectAtIndexPath:indexPath];

            [cell setMessageText:[message msgText]];
        }
            break;
        case NSFetchedResultsChangeMove:
            [[self tableView] insertRowsAtIndexPaths:newArray
                                    withRowAnimation:UITableViewRowAnimationFade];

            [[self tableView] deleteRowsAtIndexPaths:oldArray
                                    withRowAnimation:UITableViewRowAnimationFade];

            break;
    }
}


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