如何以编程方式切换 UITableView 的 NSFetchedResultsController(或其谓词)? [英] How to switch UITableView's NSFetchedResultsController (or its predicate) programmatically?

查看:12
本文介绍了如何以编程方式切换 UITableView 的 NSFetchedResultsController(或其谓词)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UITableView,它显示了大量名为文档"的实体的子集.该子集由另一个实体选择"定义.选择是命名的、有序的文档列表.

I have a UITableView that displays a subset of a large number of entities named "Documents". The subset is defined by another entity "Selection". Selections are named, ordered list of documents.

它工作正常,除非我想在运行时更改显示的选择.我只得到一个空白列表.

It Works fine, except when I want to change the displayed selection at run time. I get only a blank list.

基本上,我需要更改我的 NSFetchedResultsController 持有的谓词,以便新的谓词使用另一个选择.我无法让它发挥作用.我的最后一次尝试是完全摆脱 NSFetchedResultsController 并重新分配它:

Basically, I need to change the predicate that my NSFetchedResultsController holds so that the new predicate uses the another Selection. I couldn't make it work. My last attempt is to get rid of the NSFetchedResultsController altogether and reallocate it:

- (void) displaySelection:(Selection *)aSet
{
 self.currentSelection = aSet;
 self.fetchedResultsController = nil;
 // methods here don't all use the property but directly the ivar, so we must trigger the getter
 [self fetchedResultsController];
 [self.tableView reloadData];
}

当然,NSFetchedResultsController getter 做了正确的事情:

And of course, the NSFetchedResultsController getter does the right thing:

- (NSFetchedResultsController *)fetchedResultsController
{
    if (fetchedResultsController != nil) { return fetchedResultsController; }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DocInSelection" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"selection.identifier like %@", currentSelection.identifier];
    [fetchRequest setPredicate:predicate];
<snip>
    [fetchRequest setSortDescriptors:sortDescriptors];
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;
<snip>
    return fetchedResultsController;
}

此代码第一次起作用,因为初始选择已设置.但是,当调用 displaySelection: 时,tableview 变为空白.

This code works the first time, because the Initial Selection is set. When displaySelection: is called, though, the tableview becomes blank.

NSFetchedResultsController 获取请求 - 更新谓词和 UITableView 中提出了一个非常相似的问题

答案是去掉 NSFetchedResultsController.我不想这样做,因为 NSFetchedResultsController 在这里带来了很多有用的东西(例如缓存、部分加载......).问题仍然存在:如何在由 NSFetchedResultsController 支持的 UITableView 中切换"数据,其中切换"意味着具有不同的谓词,甚至(在我的情况下)不同的实体.

And the answer was to get rid of the NSFetchedResultsController. I don't want to do that, because NSFetchedResultsController brings a lot of useful goodies here (eg caching, partial loading...). The question still stands: how to "switch" data in a UITableView backed by a NSFetchedResultsController, where "switch" means having a different predicate, or even (not in my case) a different entity.

请注意,为了完整起见,由于从 Selection 到 Document 的多对多关系是有序的,它是通过一个称为 DocInSelection 的中间轻量级实体处理的,它有一个排序"属性和两个多-与文档和选择的一对一关系.

Note for the sake of completeness, that since the many-to-many relationship from Selection to Document is ordered, it is handled through an in-between lightweight entity called DocInSelection, which has an "ordering" property and two many-to-one relationships to Document and Selection.

感谢您的任何建议.

推荐答案

在我发布我的问题后,我尝试了另一个问题的 OP 显示的代码的变体.这个对我有用.这是:

After I posted my question, I tried a variant of the code the OP of the other question showed. It works for me. Here it is:

- (void) displaySelection:(Selection *)aSet
{
    if (aSet != self.currentSelection) {
        self.currentSelection = aSet;

        NSFetchRequest *fetchRequest = [[self fetchedResultsController] fetchRequest];
        NSPredicate *predicate = nil;
        NSEntityDescription *entity = nil;
        entity = [NSEntityDescription entityForName:@"DocInSelection" inManagedObjectContext:managedObjectContext];
        predicate = [NSPredicate predicateWithFormat:@"selection.identifier like %@", currentSelection.identifier];
        [fetchRequest setEntity:entity];
        [fetchRequest setPredicate:predicate];

        [NSFetchedResultsController deleteCacheWithName:@"Root"];

        NSError *error = nil;
        if (![[self fetchedResultsController] performFetch:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }       
    }
    [self.tableView reloadData];
}

这篇关于如何以编程方式切换 UITableView 的 NSFetchedResultsController(或其谓词)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆