在不更改NSSortDescriptor的情况下更改FetchRequest时,NSFetchedResultController不更新UITableView

时间:2013-11-17 04:45:20

标签: ios iphone objective-c nsfetchedresultscontroller

我的视图控制器中有一个UITableView和一个UISegmentControl。 视图控制器有两个段。当用户点击一个段时,我在viewController中优化数据,它应该在UITableView中更新。这不起作用。

使用NSFetchedResultsController显示数据,其中datasource是CoreData表。 它们使用相同的NSSortDescriptor,但不是相同的谓词。

我观察到当我更改NSSortDescriptor时,它可以工作,所以这个对象是问题的根源。

当用户点击某个细分时,我会调用此代码:

self.fetchedResultsController = nil;
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
}

它以这种方式更新NSFetchedResultsController:

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }
    //get the segment index:
    NSUInteger selectedState = self.chooseTableSegmentedControl.selectedSegmentIndex;

    //Update the fetched result consequently:
    NSManagedObjectContext *context = self.managedObjectContext;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"
                                              inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:NO];
    NSPredicate *predicate;

    if (selectedState == 0) {
        [fetchRequest setSortDescriptors:@[dateDescriptor]];

    } else if (selectedState == 1) {
        predicate = [NSPredicate predicateWithFormat:
                                  @"postedByUser == 0"];
        [fetchRequest setSortDescriptors:@[dateDescriptor]];

    }
    [fetchRequest setPredicate:predicate];
    [fetchRequest setFetchBatchSize:7];

    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                        managedObjectContext:context
                                          sectionNameKeyPath:nil
                                                   cacheName:@"Root"];
    _fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

有什么想法吗?非常感谢!

1 个答案:

答案 0 :(得分:4)

创建新的抓取结果控制器并调用performFetch后,您必须使用reloadData重新加载表格视图。 performFetch不会触发FRC委托方法。

更新:当获取请求发生变化时,必须删除FRC缓存(使用deleteCacheWithName:)。但缓存仅适用于sectionNameKeyPath:,因此您也可以设置cacheName:nil来解决问题。