我在使用NSFetchResultController的iOS应用程序中有一个聊天面板。提取时间如下:
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
DataSource *dataSource = [DataSource getInstance];
[NSFetchedResultsController deleteCacheWithName:@"MessageList"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:_CHAT_MESSAGE_ENTITY_ inManagedObjectContext:dataSource.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
//Predicate
DataClass *dataClass = [DataClass getInstance];
NSPredicate *predicate;
if ([self.chatType intValue] == SINGULAR_CHAT_TYPE) {
Contact *receiver = [self.members objectAtIndex:0];
predicate = [NSPredicate predicateWithFormat:@"(senderUid LIKE %@ AND receiverUid LIKE %@) OR (senderUid LIKE %@ AND receiverUid LIKE %@)", [dataClass getKeychainValueWithKey:_USER_ID_IDENTIFIER_], receiver.contactUid, receiver.contactUid, [dataClass getKeychainValueWithKey:_USER_ID_IDENTIFIER_]];
}
else { // group chat
}
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"messageDate" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:dataSource.managedObjectContext sectionNameKeyPath:@"messageId" cacheName:@"MessageList"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"%@:Unresolved error in fetchedResultsController performFetch %@List, %@", _CHAT_MESSAGE_ENTITY_,error, [error userInfo]);
//abort();
}
return _fetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.chatTableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
case NSFetchedResultsChangeInsert:
[self.chatTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.chatTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
default:
return;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.chatTableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
// case NSFetchedResultsChangeUpdate:
// [self configureCell:[chatTableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
// break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.chatTableView reloadData];
[self.chatTableView endUpdates];
}
这个提取工作正常,当我打开视图控制器时,所有先前的消息都会在桌面上看到它们应该是。但是,当我键入新消息并按“发送”按钮时,不仅会显示新消息,还会在获取之前显示最后一条消息。 我得到了行数,看到有2个丢失的对象。 尽管如此,如果我停止应用程序并再次运行,这些最后2条消息将被获取并显示。
同样的问题是发生对话面板。换句话说,在发送消息后,我的会话视图控制器需要更新。然而,它的最后一次谈话(选择一次)正在迷失。
我将消息和对话保存为:
DataSource *ds = [DataSource getInstance];
ChatMessage *newMsg = (ChatMessage*)[ds createInsertObject:_CHAT_MESSAGE_ENTITY_];
[newMsg loadFromDictionary:tmpDict];
Chat *chat = (Chat*)[ds findOrCreateWithIdentifier:[[headers objectForKey:CHAT_TYPE] stringValue]:[headers objectForKey:@"receiverUid"] :_CHAT_ENTITY_];
[chat loadHeaders:headers andMessage:newMsg];
newMsg.chat = chat;
[ds coreDataSaveContext];
在这次保存之后,我告诉我的聊天视图控制器:
- (void)refreshPage {
[self.fetchedResultsController performFetch:nil];
[self.chatTableView reloadData];
[self takeTableContentsUp];
}
我是否遗漏了有关获取结果控制器的内容?为什么会出现这个问题以及如何解决?
谢谢!
编辑:如果我在保存邮件中删除“聊天”实体,只需保存聊天面板即可。因此,问题是多个实体彼此交互。 我应该如何编辑和保存2个实体到核心数据,并获取没有问题?