直接使用 NSFetchedResultsController vs NSManagedObjectContext 获取

Posted

技术标签:

【中文标题】直接使用 NSFetchedResultsController vs NSManagedObjectContext 获取【英文标题】:Fetching using NSFetchedResultsController vs NSManagedObjectContext directly 【发布时间】:2012-12-31 10:40:49 【问题描述】:

我遇到了一个问题并且可以解决它,但我很想知道究竟是什么原因。

我有一个共享类,它应该给我员工的休假/休假信息。我的实用程序类中有一个获取请求,它提供了获取对象的离开信息。

这部分代码负责取叶子:

#define FETCH_DIRECTLY 1
-(NSArray*)targetHoursArrayOnDate:(NSDate*)inDate

#if FETCH_DIRECTLY
    NSFetchRequest *targetHoursFR = [CSUtilities fetchRequestForVacationOrLeave];
    CSAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSArray *arrayOfTargetHours = [[appDelegate managedObjectContext] executeFetchRequest:targetHoursFR
                                                      error:NULL];
#else
    NSArray *arrayOfTargetHours = [self.targetHoursFRC fetchedObjects];
#endif
    NSPredicate *checkDatePredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings)
                                       
                                           BOOL dateExists = NO;
                                           if ([evaluatedObject isKindOfClass:[CSTargetHours class]])
                                           
                                               CSTargetHours *aTargetHour = (CSTargetHours*)evaluatedObject;
                                               if ([aTargetHour.leaveDate isEqualToDate:inDate])
                                                   dateExists = YES;
                                           
                                           return dateExists;
                                       ];

    NSArray *targetHoursOnQueriedDate = [arrayOfTargetHours filteredArrayUsingPredicate:checkDatePredicate];
    if (0==[targetHoursOnQueriedDate count])
        targetHoursOnQueriedDate = nil;
    return targetHoursOnQueriedDate;

请注意,FETCH_DIRECTLY 是我怀疑的场景。如果我使用 FRC 来获取叶子,它会失败。而如果我直接使用 App 委托的 managedObjectContext,它会成功获取对象!这让我很困惑。

创建我的 FRC 的方法在这里:

@synthesize targetHoursFRC = targetHoursFRC_;
-(NSFetchedResultsController*)targetHoursFRC

    if (nil==targetHoursFRC_)
    
        NSFetchRequest *targetHoursFR = [CSUtilities fetchRequestForVacationOrLeave];
        CSAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        targetHoursFRC_ = [[NSFetchedResultsController alloc] initWithFetchRequest:targetHoursFR
                                                              managedObjectContext:appDelegate.managedObjectContext
                                                                sectionNameKeyPath:nil
                                                                         cacheName:nil];
    
    return targetHoursFRC_;


- (id)init

    self = [super init];
    if (self) 
        [self.targetHoursFRC performFetch:NULL];
    
    return self;

我在这里唯一遗漏的是,我没有将代表设置为 FRC。但我不需要它,因为我对听这些变化不感兴趣。相反,当其他模块询问时,请假/假期信息应该准备好。

coredata 的内部是否以某种方式设计为仅在 FRC 有任何委托时才通知 FRC 更改?失败了,无论我们何时触发 FRC 上的 -fetchedObjects 调用,它都会给出一些旧的结果集?

谢谢, 拉杰

【问题讨论】:

【参考方案1】:

如果您没有为 FRC 设置委托,并且至少实现了一个 FRC 委托功能(例如controllerDidChangeContent:),则 FRC 以“无跟踪模式”运行。

这意味着fetchedObjects 将始终返回初始performFetch: 操作的结果集。

(请参阅NSFetchedResultsController 文档中的“概述”部分)。

【讨论】:

以上是关于直接使用 NSFetchedResultsController vs NSManagedObjectContext 获取的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能两次获取相同的数据? NSFetchedResultsController 为空

如何按创建 UITableViewCell 时计算的值对 UITableView 进行排序?

使用 linq 生成直接更新,无需选择

为啥使用闭包进行赋值而不是直接为键赋值?

如何使用 .Net 直接读取磁盘?

不使用代理直接将日志发送到 Loki