我正在尝试将AFIncrementalStore与MagicalRecord一起使用。
我有一类具有少量属性的啤酒(来自BreweryDB网络服务)。为了获取啤酒,我使用[Beer MR_fetchAllWithDelegate:self]返回NSFetchedResultsController实例(我抓住并分配给beerFetchController)并使用该控制器执行实际获取。您还可以看到我将视图控制器设置为方法的委托,然后将该视图控制器设置为beerFetchController的委托。到现在为止还挺好。我有一个显示啤酒的表视图,我实现了方法
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.beersTable reloadData];
}
因此,只要AFIncrementalStore获取数据,将其放入上下文中,控制器就会得到通知,然后应该调用此方法,并刷新表。问题是,这个委托方法根本没有被调用!经过一番调查后,我得出了一些结论。
+ (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id<NSFetchedResultsControllerDelegate>)delegate;
{
return [self MR_fetchAllWithDelegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
}
+ (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id<NSFetchedResultsControllerDelegate>)delegate inContext:(NSManagedObjectContext *)context;
{
NSFetchRequest *request = [self MR_requestAllInContext:context];
NSFetchedResultsController *controller = [self MR_fetchController:request delegate:delegate useFileCache:NO groupedBy:nil inContext:context];
[self MR_performFetch:controller];
return controller;
}
问题在于,[NSManagedObjectContext MR_contextForCurrentThread]将返回子上下文,其父级是AFIncrementalStore内部使用的后备上下文。 AFIncrementalStore保存到父级而不是子级,因此控制器不知道任何更改,并且不调用委托方法。我能够像这样修改方法:
+ (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id<NSFetchedResultsControllerDelegate>)delegate inContext:(NSManagedObjectContext *)context;
{
NSFetchRequest *request = [self MR_requestAllInContext:context];
NSFetchedResultsController *controller = [self MR_fetchController:request delegate:delegate useFileCache:NO groupedBy:nil inContext:context.parentContext];
[self MR_performFetch:controller];
return controller;
}
不是将控制器绑定到MR_contextFromCurrentThread返回的上下文,而是将其绑定到其父级。然后,正如预期的那样工作原理,上下文被改变,控制器看到,并且调用委托方法。问题是,有没有办法将更改从父上下文推送到子上下文,所以我不必更改方法实现?
+ (NSManagedObjectContext *) MR_contextForCurrentThread;
{
if ([NSThread isMainThread])
{
return [self MR_defaultContext];
}
else
{
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
NSManagedObjectContext *threadContext = [threadDict objectForKey:kMagicalRecordManagedObjectContextKey];
if (threadContext == nil)
{
threadContext = [self MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
[threadDict setObject:threadContext forKey:kMagicalRecordManagedObjectContextKey];
}
return threadContext;
}
}