首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >核心数据后台慢速和后台保存,sqlite后台和mergeChangesFromContextDidSaveNotification

核心数据后台慢速和后台保存,sqlite后台和mergeChangesFromContextDidSaveNotification
EN

Stack Overflow用户
提问于 2012-12-14 01:27:18
回答 1查看 612关注 0票数 0

我正在为我的应用程序写一个更新,我需要在数据库内插入30张图片。现在我正在使用核心数据,它可以正确地保存,但需要10秒……所以我决定在后台发送保存过程。我有一个处理图像数组的for循环,每转一次我就创建一个NSmanagedObject并保存它。有了这个基础,我尝试了不同的解决方案,没有什么是正确的:

1

代码语言:javascript
复制
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---

代码语言:javascript
复制
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约束失败的错误?

EN

回答 1

Stack Overflow用户

发布于 2012-12-14 03:21:21

您的开销很可能来自于每次保存图像时创建一个新的上下文。这是一项昂贵的手术。您只需要两个上下文,一个用于主队列,另一个用于串行后台队列。此外,请注意,苹果公司建议不要将图像存储在数据库中,我的经验也是如此。您应该只将映像路径保留在数据库中,而将映像保留在文件系统中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13865206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档