我正在为我的应用程序写一个更新,我需要在数据库内插入30张图片。现在我正在使用核心数据,它可以正确地保存,但需要10秒……所以我决定在后台发送保存过程。我有一个处理图像数组的for循环,每转一次我就创建一个NSmanagedObject并保存它。有了这个基础,我尝试了不同的解决方案,没有什么是正确的:
1
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Add code here to do background processing
//context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSManagedObjectContext *contextTemp = [[NSManagedObjectContext alloc] init];
NSPersistentStoreCoordinator *store=[(RecipesAppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];
contextTemp.persistentStoreCoordinator=store;
Recipe *recipe = (Recipe *)[contextTemp objectWithID:MoID];
NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:contextTemp];
[image setValue:[[ArrayDizionariImmagini objectAtIndex:i] valueForKey:@"image"] forKey:@"image"];
[image setValue:[NSDate date] forKey:@"data"];
recipe.image=image;
[contextTemp save:nil];
});这个方法以正确的方式保存所有内容,但它需要10秒,就像我在主线程中的第一次尝试一样,所以它是无用的…
2---
dispatch_queue_t request_queue = dispatch_queue_create("com.doeatraw.saveimages", NULL);
dispatch_async(request_queue, ^{
// Create a new managed object context
// Set its persistent store coordinator
AppDelegate *theDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *newMoc = [[NSManagedObjectContext alloc] init];
[newMoc setPersistentStoreCoordinator:[theDelegate persistentStoreCoordinator]];
// Register for context save changes notification
NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:newMoc];
BOOL success = [newMoc save:nil];
});
dispatch_release(request_queue);
- (void)mergeChanges:(NSNotification*)notification
{
context = [(RecipesAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
[context performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:NO];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}在此尝试中,我只在所有更新结束时保存一个临时ManagedObjectContext,然后尝试合并更改。通过这种方式,我可以在后台保存所有的图像,并且我的UI始终保持响应。但如果我关闭并重新打开应用程序,我所有的积蓄都是losts...so,很明显核心数据并没有任何真正的合并。
3----------
我还尝试通过sql直接插入所有的数据。我已经把所有的在后台,它似乎是好的,ui是响应性的,所有的数据都是inserted...Anyway出了点问题。当我尝试访问相同的表时(通过在应用程序中启动其他独立的方法来查询相同的表),sql会使应用程序崩溃,而不会在日志中出现错误(只有一次我收到错误消息"Constraint Failed")。我可以提取并可视化插入的图像,但不能在表中执行另一次插入(通过核心数据)。
有人能帮我吗?我知道NSManagedObjectContext不是线程安全的,但是我试着遵循我的一些attemps...Maybe中的文档指南,我错过了一些东西……我尝试保存的是一个nsmanagedobject,它将图像作为关系。我如何才能真正合并我的上下文?或者我可以如何处理sqlite约束失败的错误?
发布于 2012-12-14 03:21:21
您的开销很可能来自于每次保存图像时创建一个新的上下文。这是一项昂贵的手术。您只需要两个上下文,一个用于主队列,另一个用于串行后台队列。此外,请注意,苹果公司建议不要将图像存储在数据库中,我的经验也是如此。您应该只将映像路径保留在数据库中,而将映像保留在文件系统中。
https://stackoverflow.com/questions/13865206
复制相似问题