目标C - 获取结果控制器在插入后获取较少的对象

时间:2016-09-28 07:41:10

标签: ios objective-c uitableview nsfetchedresultscontroller reloaddata

我在使用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个实体到核心数据,并获取没有问题?

0 个答案:

没有答案