2

我已经使用通常的样板代码设置了一个 Core Data 应用程序,并且 RootViewController 通过调用它来初始化 FRC:

- (NSFetchedResultsController *)fetchedResultsController 
{
    if (__fetchedResultsController != nil) 
    {
        return __fetchedResultsController;
    }
    // configure the fetchRequest, sectionKey and cacheName
    __fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest: fetchRequest 
                                                                    managedObjectContext: self.managedObjectContext 
                                                                      sectionNameKeyPath: sectionKey 
                                                                               cacheName: cacheName];
    return __fetchedResultsController;
}

我见过的所有示例代码都是这样做的。但是,我有一个庞大的数据集和超过 15,000 个条目,在 iPhone 4S 上启动应用程序大约需要 5 秒。这是启用缓存(没有它,需要 11 秒)和索引属性。

所以我希望能够显示一个UIActivityIndicatorView应用程序正在等待加载。我知道通常如何在后台线程中加载核心数据对象,然后将它们合并回主线程,但是如何在后台线程中初始化 FRC,以便在后台加载和分割所有对象?

我知道我可以加载所有对象并将它们在后台线程中分区到自定义字典中并使用它来呈现数据,但我宁愿使用标准的 FRC 调用和委托。

谢谢。

4

2 回答 2

3

我不太确定NSFetchedResultsController在后台使用 是什么意思,但根据我的经验,您可以简单地为您的 fetch 请求设置批量大小,如下所示:

[fetchRequest setFetchBatchSize:20];

以这种方式,在启动期间加载前 20 个元素,当您滚动下一个 20 时,依此类推。此外,您可以只选择要获取的属性- (void)setPropertiesToFetch:(NSArray *)values

另一种方法是让(后台)任务开始在后台获取对象。我认为当在后台获取时,对象会以某种方式被缓存(但我不太确定),因此您可以更快地从主线程访问它们。

希望能帮助到你。

于 2012-06-06T07:58:36.290 回答
1

我想我已经弄清楚了……您可以在后台线程中创建 FRC 并在主线程中进行获取:

- (NSFetchedResultsController *)fetchedResultsController 
{
    if (__fetchedResultsController != nil) 
    {
        return __fetchedResultsController;
    }

    // create something to pass back to the first time FRC is initialized without fetching
    __block NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    aFetchedResultsController.delegate = self;
    [self.list_spinner startAnimating];

    dispatch_async(self.filterMainQueue, ^{

           NSFetchedResultsController *newFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest: fetchRequest 
                                                                                                         managedObjectContext: self.managedObjectContext 
                                                                                                           sectionNameKeyPath: sectionKey 
                                                                                                                    cacheName: cacheName];
           dispatch_async(dispatch_get_main_queue(), ^{ 
               // stop the spinner here
               [self.list_spinner stopAnimating];

               NSError *error = nil;
               if (![newFetchedResultsController performFetch:&error]) 
               {
                   NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                   [SimpleListAppDelegate showCoreDataError: @"SimpleListViewController - FRC"];
               }
               __fetchedResultsController = nil;
               newFetchedResultsController.delegate = self;
               __fetchedResultsController = newFetchedResultsController;
               [self.tableView reloadData];
           });
         });

    return aFetchedResultsController;
}
于 2012-06-07T00:30:56.760 回答