我正在编写一个使用许多 NSFetchedResultsControllers (FRC) 的应用程序,每个应用程序用于我的数据模型中的不同托管对象子类。其中几个 FRC 是 UITableViewControllers 的一部分,但有几个不是。我有两个问题:第一,当我向 MOC 添加新对象时,为什么我的一个 FRC 没有更新,第二,我是否应该为此目的使用 FRC?我认为它可以让我不必在整个代码中放置获取请求,但也许只有将 FRC 与 tableview 或其他此类对象一起使用才有意义。
所以,这里是详细信息。
不绑定(bind)到 tableview 的 FRC 之一是跟踪时间表的 FRC。 SetScheduleViewController 具有以下属性(以及其他属性),这些属性是通过父 View Controller 传入的:
@property (weak, nonatomic) NSFetchedResultsController *scheduleFetchedResultsController;
@property (weak, nonatomic) NSManagedObjectContext *managedObjectContext;
这个 FRC 是由另一个对象(它维护一个指向它的强指针)通过以下代码创建的
- (NSFetchedResultsController *)scheduleFetchedResultsController {
if (_scheduleFetchedResultsController != nil) {
return _scheduleFetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName"Schedule" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey"start" ascending:NO];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *fRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
NSError *error = nil;
if (![fRC performFetch:&error]) {
IFLErrorHandler *errorHandler;
[errorHandler reportErrorToUser:error];
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
self.scheduleFetchedResultsController = fRC;
return self.scheduleFetchedResultsController;
}
(顺便说一句:cacheName 设置为 nil 的原因是我似乎只能将缓存名称分配给此应用程序中的众多 FRC 中的一个,或者应用程序崩溃......如果只有一个 FRC给定一个缓存名称,其余的缓存名称设置为 nil,一切似乎都很好,尽管我担心没有缓存,随着持久存储大小的增长,性能可能会很糟糕......但这是另一回事)
在SetScheduleViewController 中,可以创建或删除一个计划,并在加载SetScheduleViewController 时加载最近创建的计划。创建计划时,会创建一个新的计划管理对象,然后将 MOC 保存如下:
Schedule *newSchedule= [NSEntityDescription insertNewObjectForEntityForName"Schedule" inManagedObjectContext:self.managedObjectContext];
newSchedule.start=newStartTime;
//etc
NSError *saveError;
if (![self.managedObjectContext save:&saveError]) {
// 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 %@, %@", saveError, [saveError userInfo]);
abort();
这成功保存了新的 MO,但 FRC 没有更新...我已经检查了几种方法...例如,如果在保存新计划后我重新输入 SetScheduleViewController 并检查 [[self.scheduleFetchedResultsController fetchedObjects] count] 它没有增加。但是,如果我退出应用程序并再次打开它,你瞧,FRC 获取的对象计数会增加,并且新对象确实存在。
我应该注意到 scheduleFetchedResultsController 没有分配委托(delegate),这与 FRC 附加到 tableviewcontrollers 不同,它们都可以正常工作。我没有分配委托(delegate),因为据我所知,tableviewcontrollers 中的 FRC 委托(delegate)方法仅在 FRC 更改内容时处理更新 tableview...我没有看到任何委托(delegate)方法添加新对象并保存 MOC 时刷新 FRC 本身。
所以,我的两个问题又是:1) 为什么 FRC 不刷新(以及我如何让它刷新),2) 使用 FRC 来管理未绑定(bind)的托管对象的获取结果是否有意义到 tableview ,我是否应该在每次需要访问对象列表时简单地从 MOC 执行新的提取?
非常感谢任何帮助。
Best Answer-推荐答案 strong>
在 NSFetchedResultsController 文档中指出,如果没有设置委托(delegate),FRC 处于“无跟踪”模式。此外,委托(delegate)必须至少实现一种变更跟踪委托(delegate)方法才能启用变更跟踪。
委托(delegate)不必是表格 View Controller ,因此您可以使用您的
SetScheduleViewController 作为委托(delegate),只需实现 controllerDidChangeContent: 委托(delegate)方法。在该方法中,更新的
fetchedObjects 是可用的,你可以例如更新 View 中的任何 UI 元素
Controller 。
更新:从 parentVC 传递 FRC 没有多大意义。 每个 View Controller 都应该有自己的 FRC。所以 scheduleFetchedResultsController 应该是 childVC 中的一个方法。由于 FRC 是在 getter 方法中“延迟”创建的,因此必须在某个地方调用 getter。
在 TableView Controller 的情况下,发生这种情况是因为所有 TableView 数据源方法
访问 self.fetchedResultsController 。
如果您的 childVC 不访问 self.fetchedResultsController 那么 FRC
不会被创建。这可能是在 viewDidLoad 中调用 [self.fetchedResultsController performFetch:&error] 的原因,正如另一个答案中所建议的那样,解决了您的问题。
委托(delegate)方法 controllerDidChangeContent: 如果结果会被调用
在 childVC 的生命周期内设置更改。这就是使用 FRC 的意义所在。
如果您只想在加载 childVC 时获取当前对象集,那么
你不需要 FRC,你可以执行一个简单的 fetch,例如在 viewDidLoad .
关于ios - 刷新未绑定(bind)到 uitableview 的 nsfetchedresultscontroller,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/20604490/
|