0

我正在为我的应用程序编写更新,我需要在 db 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 始终保持响应。但是,如果我关闭并重新打开应用程序,我所有的积蓄都会丢失......所以很明显核心数据没有任何真正的合并。

3------------------------------------------------ ------------

我也尝试通过sql直接插入所有数据。我已经把所有的东西都放在了后台,看起来没问题,ui 是响应式的并且所有的数据都被插入了......无论如何都出了问题。当我尝试访问同一个表时(通过在应用程序中启动查询同一个表的其他独立方法),sql 使应用程序崩溃而日志中没有错误(只有一次我收到错误“约束失败”)。我能够提取和可视化插入的图像,但我不能在表格中再插入一个(按核心数据)。

有人可以帮助我吗?我知道 NSManagedObjectContext 不是线程安全的,但我尝试在我的一些尝试中遵循文档指南......也许我错过了一些东西......我试图保存的是一个带有图像作为关系的 nsmanagedobject。我如何才能真正合并我的上下文?或者我可以用错误sqlite Constraint Failed做什么?

4

1 回答 1

1

Most probably your overhead comes from creating a new context each time you save an image. That's an expensive operation. You only need 2 contexts, one for the main queue and the second for a serial background queue. Also, please note that Apple advises against storing images in the database, the experience I have says the same thing. You should only keep the image path in the database, and keep the image on the file system.

于 2012-12-13T19:21:21.390 回答