2

我正在尝试将 AFIncrementalStore 与 MagicalRecord 一起使用。

我有一个带有少量属性的 Beer 类(来自 BreweryDB Web 服务)。为了获取啤酒,我使用 [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;
    }
}
4

0 回答 0