【问题标题】:NSfetchedResultsController changes not reflecting to UINSfetchedResultsController 更改未反映到 UI
【发布时间】:2018-03-27 17:24:22
【问题描述】:

NSFetchedResultsController 的问题是我获取了数据并填充了UITableView,其中cacheName 设置为nil。后来当我更改NSFetchedResultsControllerpredicate 并调用perfromFetch 时,它不会刷新UITableView 但是NSFetchedResultsController 中的数据会更新。还有一件事,NSFetchedResultsControllerDelegate 方法也没有被调用。

提前致谢。

已编辑:添加代码

NSFetchedResultsControllerDelegate

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

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

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

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeMove:
        case NSFetchedResultsChangeUpdate:
            break;
    }
}

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

NSFetchedResultsController

- (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController) {
        return _fetchedResultsController;
    }

    NSManagedObjectContext *context = [GmailDBService sharedService].managedObjectContext;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Thread"];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"historyId" ascending:NO];
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(messages, $m, ANY $m.labels.identifier == %@).@count > 0", self.label.identifier];
    fetchRequest.sortDescriptors = @[sortDescriptor];
    fetchRequest.fetchBatchSize = 20;

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
    _fetchedResultsController.delegate = self;
    [_fetchedResultsController performFetch:nil];

    return _fetchedResultsController;
}

谓词刷新

- (IBAction)unwindToThreadsController:(UIStoryboardSegue *)segue
{
    self.fetchedResultsController.fetchRequest.predicate = [NSPredicate predicateWithFormat:@"identifier == %@", @"15f1919682399cc9"];
    [self.fetchedResultsController performFetch:nil];
}

【问题讨论】:

  • 你把 NSFetchedResultsController 委托设置为 self 吗??
  • 是的,我做了并稍后交叉检查该值。代表完好无损,和以前一样。
  • 您能否发布一些代码,很难假设您的项目中可能会发生什么。发布代码的相关部分将帮助我们为您提供更好的解决方案
  • 我已经贴出代码了,请看一下。
  • 代码看起来不错。您确定只有在更新谓词后才调用 FetchedResultsController 委托?最后你确定 FetchedResultsController 的 fetched 对象中的数据会随着谓词的变化而变化??

标签: ios objective-c uitableview core-data nsfetchedresultscontroller


【解决方案1】:

fetchedResultsController 不贵。您不应该害怕根据需要创建和销毁它们。当您需要更改谓词时,丢弃当前的fetchedResultsController 并创建一个新的。完成后不要忘记重新加载 tableView。

更改不会触发fetchedResultsController,因为您正在监视线程,但您的谓词是基于消息的。因此,当消息更改时,它不会触发fetchedResultsController 的更改。控制者只监控一个实体的变化,并不期望其他实体的变化会影响它。您可以通过以下几种方式解决此问题:

  1. 设置您的fetchedResultsController 以查看消息并按线程分组,然后仅将每个部分(即线程)显示为一行。
  2. 每次更改消息时,也会更改其线程(就fetchedResultsController 而言,message.thread.threadId = message.thread.threadId 将被视为更改)。

fetchBatchSize 也不受 fetchedResultsController 的尊重,因此为了清楚起见,您应该将其删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    相关资源
    最近更新 更多