目标是在应用程序加载时加载~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。有任何改进或修复的想法吗?
答案 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
属性吗?