启动Core Data应用程序时在后台配置NSFetchedResultsController

时间:2012-06-06 05:26:07

标签: core-data nsfetchedresultscontroller nsmanagedobjectcontext

我已经使用通常的样板代码设置了一个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调用和委托。

感谢。

2 个答案:

答案 0 :(得分:2)

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

[fetchRequest setFetchBatchSize:20];

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

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

希望它有所帮助。

答案 1 :(得分: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;
}