如何以编程方式切换 UITableView 的 NSFetchedResultsController(或其谓词)? [英] How to switch UITableView's NSFetchedResultsController (or its predicate) programmatically?
问题描述
我有一个 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屋!