在我的项目中,我应该下载以这种方式制作的JSON文件:
[{"id":"2","n":"One"},{"id":"2","n":"Two"},{"id":"2","n":"Three"},...]
我的代码是:
- (void) startPopulate:(NSArray *)array{
NSManagedObjectContext *context = [[self sharedAppDelegate] managedObjectContext];
NSFetchRequest *fetchRequest=[NSFetchRequest fetchRequestWithEntityName:@"Myentity"];
NSError *error = nil;
for (id element in array){
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"id == %@",[element objectForKey:@"id"]]];
Myentity *myE = [[context executeFetchRequest:fetchRequest error:&error] lastObject];
//update
if (myE != nil){
myE.id_e = [element objectForKey:@"id"];
myE.name = [element objectForKey:@"n"];
}
//new element
else{
Myentity *myE = [NSEntityDescription insertNewObjectForEntityForName:@"Myentity" inManagedObjectContext:context];
myE.name = [element objectForKey:@"n"];
myE.id_e = [element objectForKey:@"id"];
}
}
if (![context save:&error]) {
NSLog(@"couldn't save: %@", [error localizedDescription]);
}
else{
NSLog(@"DB UPDATED");
}
}
正如你所看到的,我在方法中传递了字典数组,并检查实体是否存在。 它工作正常,我没有细节问题。 “问题”,如果它是调用它的方式,是我有12000个元素,这个方法运行大约53秒。这非常慢。 我可以采用什么类型的解决方案来使其更快? 或者我应该把这个方法放在后台进程中? 感谢
答案 0 :(得分:0)
你应该把它放在后台进程吗?
绝对。启动后台线程并从主上下文创建子上下文以完成所有工作。
还能做些什么
您对托管对象上下文所做的每个未保存的更改都存储在内存中。在保存之前进行数千次更改是不可取的,因为它会占用大量内存,但节省时间也需要很长时间。
您可以批量更新,一次更改100个,并保存每个块100个。
<强>替代强>
如果您总是为应用程序加载这些项目,那么您也可以将它们预加载到数据库中并将其捆绑到应用程序本身。
这样你就不需要在运行时保存它们,因为它们已经在那里。
答案 1 :(得分:0)
以下是使用核心数据时创建后台线程的方法:
dispatch_queue_t fetchQ = dispatch_queue_create("JSON Fetcher", NULL);
dispatch_async(fetchQ, ^{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = self.mainMOC;
[context performBlock:^{
// implement your own background code here
NSError *error;
if(![context save:&error]) {
// handle error
}
}];
});
您还需要保存结果,以便将它们传播到mainMOC。希望它有所帮助!