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

我有一个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)  |
                          -----------------           -----------------

数据来自一个服务器,它总是为MainTopic填充所有消息(这不在我手中) .

对于CoreData,我有一个实现为单例的Controller . 它有一个mainContext(NSManagedObjectContext),由NSFetchedResultsController使用 . 插入新数据是在单独的NSManagedObjectContext上完成的,该文件在保存时调用mainContext上的mergeChangesFromContextDidSaveNotification :.

Thread类有一个比较:-Method,因此它也可以用于sortdescriptor .

回到UITableViewController:

在viewDidLoad上,它创建NSFetchedResultsController,它获取topicID的所有消息,sectionNameKeyPath设置为“thread”并在FetchedResultsController上执行提取 .

UITableView还实现了NSFetchedResultsControllerDelegate,以便在新消息到达时更新TableView . 这就是我的问题开始的地方 .

从服务器获取新内容后,Table View可能如下所示

______________________________________
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|
| Thread: Second thread              |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|

现在有人将消息(消息3)写入第一个线程,数据从服务器获取(用户保留在表视图中) . 现在表视图看起来像这样

______________________________________
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 3                          |
|____________________________________|
| Thread: Second thread              |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|

如您所见,第一个线程的节 Headers 出现两次 .

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

______________________________________
| Thread: First thread               |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
| Message 3                          |
|____________________________________|
| Thread: Second thread              |
|____________________________________|
|____________________________________|
| Message 1                          |
| Message 2                          |
|____________________________________|

所以我认为错误必须在NSFetchedResultsControllerDelegate方法中的某处,但是因为它们看起来“正常” .

#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];
}

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