CoreData NSFetchRequest 返回结果,但对象的节数返回 0

Posted

技术标签:

【中文标题】CoreData NSFetchRequest 返回结果,但对象的节数返回 0【英文标题】:CoreData NSFetchRequest returns results but section number of objects returns 0 【发布时间】:2013-01-28 11:32:41 【问题描述】:

我目前正在尝试编写我的第一个 CoreData 项目并且非常困惑。我正在使用以下代码来设置获取结果控制器:

- (NSFetchedResultsController *)fetchedResultsController 

    if (_fetchedResultsController != nil)
        return _fetchedResultsController;

    Singleton *singleton = [Singleton sharedSingleton];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"MapEntity" inManagedObjectContext:[singleton managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"sName" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:8];

    // Finally check the results
    NSError *error;
    NSArray *fetchedObjects = [[singleton managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    for (MapEntity *map in fetchedObjects)
    
        NSLog(@"Maps present in database: %@", map.sName);
    


    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[singleton managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

我输入了 NSLog 来查看 fetchRequest 是否找到了结果,它确实找到了结果:

2013-01-28 11:20:14.735 WildMap_ios[10931:16a03] Maps present in database: UK Capital Cities
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: The UK
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Testing123
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: TestForPic
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Scottish Map
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Old Scotland
2013-01-28 11:20:14.736 WildMap_iOS[10931:16a03] Maps present in database: Old Scotland
2013-01-28 11:20:14.737 WildMap_iOS[10931:16a03] Maps present in database: Old Scotland
2013-01-28 11:20:14.737 WildMap_iOS[10931:16a03] Maps present in database: Field Concatination

但是,当我尝试使用我的 fetchedResultsController 来设置我的 tableView numberOfRowsInSection 时,如下所示:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    id sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];

    return [sectionInfo numberOfObjects];

'return [sectionInfo numberOfObjects];'返回 nil,即使 fetchRequest 似乎可以很好地拾取对象。

我使用这段代码很好,但是我最近向 mapEntity (iID) 添加了一个整数,它让我删除了模拟器数据,因为存储数据的结构发生了变化。在我删除数据并重新启动应用程序后,代码不再有效。

谁能帮我理解为什么会这样?我认为它不像以前那样使用命名约定,并且 fetchRequest 正在返回结果。

【问题讨论】:

【参考方案1】:

除了@Levi 的建议之外,您不应该直接在numberOfRowsInSection(或其他表视图数据源方法)中访问实例变量_fetchedResultsController。始终使用属性访问器self.fetchedResultsController

原因fetchedResultsController getter 方法在必要时创建获取的结果控制器。直接访问_fetchedResultsController 可能会返回nil

更新:另一个问题是获取的结果控制器缓存。来自文档:

重要提示:如果您使用缓存,则必须调用 deleteCacheWithName: 在更改任何获取请求之前,其 谓词或其排序描述符。您不得重复使用相同的 获取多个查询的结果控制器,除非您设置 cacheNamenil. ... 在可能的情况下,控制器使用缓存来避免重复执行的工作 设置任何部分并订购内容。缓存在您的应用程序启动期间得到维护。

因此,您应该使用cacheName:nil 或确保在更改 FRC 的任何参数时删除缓存。

【讨论】:

啊,好吧,我已经更改了我的代码以反映这一点,但它仍然无法正常工作。我一直在检查 _fetchedResultsController 是否有效,确实如此。当我打印出 '[[self.fetchedResultsController section] objectAtIndex:0]' 我得到 '<_nsdefaultsectioninfo:>',但是 section 参数仍然为零。 你能 NSLog() [self.fetchedResultsController fetchedObjects] 的内容吗? 您也可以尝试cacheName:nil创建FRC,以避免缓存数据错误的问题。 是的,它列出了所有 MapEntity 及其相关数据。这很奇怪,它正在查找条目,但它根本不会在部分中返回数字。 好的,谢谢!它是cacheName,有什么理由在数据被删除时没有被删除和释放?您能否将此添加到您的答案中,我可以接受。【参考方案2】:

在方法中的return _fetchedResultsController; 行之前,告诉NSFerchedResultsController 执行请求:

[self.fetchedResultsController performFetch:NULL];

【讨论】:

这仍然返回 nil,这是否意味着 fetch 有问题?

以上是关于CoreData NSFetchRequest 返回结果,但对象的节数返回 0的主要内容,如果未能解决你的问题,请参考以下文章

NSFetchRequest 上的 Swift2.0 CoreData 问题

Coredata NSFetchRequest DictionaryResultType 空属性 Swift

NSFetchRequest 检索 CoreData 实体中每个科目的每个学生的最高考试分数

首先对 CoreData NSFetchRequest 完全匹配进行排序

使用 Coredata 和 NSFetchRequest 进行“IN”搜索时如何格式化 NSPredicate

CoreData NSFetchRequest 返回结果,但对象的节数返回 0