我有一个(至少对我来说)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 |
|____________________________________|
如您所见,第一个线程的节标题出现两次。
如果再次打开并打开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];
}
那么,有人对我提出了一个暗示,问题可能在哪里吗?