通过魔法记录显示大量物体

时间:2015-02-15 17:05:27

标签: objective-c core-data magicalrecord

目标是在应用程序加载时加载~20k实体(在后台线程中)。然后在加载后我想在UITableView中显示那些。为此目的,如此大量的对象,我将使用fetchedResultController,批量设置为100?

这就是我试图实现它的方式:

UIApplication *application = [UIApplication sharedApplication];

__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    for(int i = 0; i <20000; i++){
        Object *object = [Object MR_createInContext:localContext];
        object.number = i;
    }
} completion:^(BOOL success, NSError *error) {
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
    [self finishedSaving];
}];

然后在finishedSaving

- (void)finishedSaving
{
    NSManagedObjectContext *context = [NSManagedObjectContext MR_contextForCurrentThread];
    self.fetchResultController = [Object MR_fetchAllGroupedBy:nil withPredicate:nil sortedBy:@"name" ascending:YES inContext:context];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    }
}

我正在冻结该方法的UI。有任何改进或修复的想法吗?

1 个答案:

答案 0 :(得分:0)

默认魔法记录的批量大小为20(请参阅源代码中的kMagicalRecordDefaultBatchSize)。

因此,使用以下大小,即使有很多要抓取的对象,UI也不应该冻结。 NSFetchedResultsController使用lazing加载机制为您做正确的工作。它抓住前20个。如果你滚动,它会抓住其他20个,依此类推。

我的猜测(我不知道魔法记录的作用)是您的保存代码(第一个代码段)没有在后台线程中运行,或者它运行不正常。你能为它提供完整的源代码吗?

关于第一个代码段,当应用程序进入前台时,您是否需要在后台运行任务?可以肯定的是,使用begin...end...并不意味着在后台运行任务,而只是告诉系统您正在做某事(对您很重要)如果可以的话,我想在后台完成。

更新1

我对MR源代码和结果进行了一些调查。

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    // This block runs in background thread
} completion:^(BOOL success, NSError *error) {
    // This block runs in main thread
}];

那么,您的Object仅包含number属性吗?