Core data 在iOS 5中使用UIManagedDocument和父/子上下文导入核心数据后台

Core data 在iOS 5中使用UIManagedDocument和父/子上下文导入核心数据后台,core-data,ios5,nsmanagedobject,nsmanagedobjectcontext,uimanageddocument,Core Data,Ios5,Nsmanagedobject,Nsmanagedobjectcontext,Uimanageddocument,我在iOS 5中有一个目录应用程序,它从XML下载数据,并使用带有NSFetchedResultsController的表视图控制器在UITableView中显示它们。数据存储在核心数据UIManagedDocument中。因为我不想在下载和导入数据时阻止主队列,所以我创建了一个用于下载数据的后台队列,以及一个新的子NSManagedObjectContext,该子NSPrivateQueueConcurrencyType用于将document.managedObjectContext作为父项导

我在iOS 5中有一个目录应用程序,它从XML下载数据,并使用带有NSFetchedResultsController的表视图控制器在UITableView中显示它们。数据存储在核心数据UIManagedDocument中。因为我不想在下载和导入数据时阻止主队列,所以我创建了一个用于下载数据的后台队列,以及一个新的子NSManagedObjectContext,该子NSPrivateQueueConcurrencyType用于将document.managedObjectContext作为父项导入数据。当我完成导入数据时,我保存:子上下文中的更改,并且这些更改会传播到父上下文。浏览目录时,我会在需要时导入其他数据。在UIManagedDocument自动保存之前,一切正常

我已使用-com.apple.CoreData.SQLDebug 1打开了核心数据SQL调试,以查看文档何时自动保存

在document.managedObjectContext中创建具有重复id的文档自动保存对象后,所有my entities id数据库都具有唯一的id参数

我做错了什么

我创建了一个简单的示例代码来重现这个问题。 代码如下: 以下是完整的Xcode项目:

下面是在后台执行导入的方法

- (void)backgroundImport
{
    static int counter;

    NSManagedObjectContext *backgroundContext;
    backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    backgroundContext.parentContext = self.document.managedObjectContext;

    [backgroundContext performBlock:^{
        NSManagedObject *entity;

        for (int i = 0; i < 2; i++) {
            entity = [self entityWithID:[NSNumber numberWithInt:arc4random() % 20 + 1]
                 inManagedObjectContext:backgroundContext];
            [entity setValue:[NSString stringWithFormat:@"A Name %d", ++counter] forKey:@"name"];
        }

        [self dumpEntitiesInManagedObjectContext:backgroundContext];

        NSError *error;
        [backgroundContext save:&error];
        if (error) NSLog(@"%@ (%@)", [error localizedDescription], [error localizedFailureReason]);

        [backgroundContext.parentContext performBlock:^{
            [self dumpEntitiesInManagedObjectContext:backgroundContext.parentContext];
        }];
    }];
}

导入上下文有10个实体,但主上下文有11个实体,ID为12的实体是重复的。似乎旧对象没有在父上下文中被修改,而是被添加了。

我仍然对核心数据和UIManagedDocument一起工作的这类内容很感兴趣,但我认为这个问题可能会解决您的问题:

它涉及使用以下方法强制临时ID在正常流量之前为永久性:
[上下文获取永久对象:[插入所有对象]错误:&error]

我仍然对核心数据和UIManagedDocument一起工作的这类内容非常熟悉,但我认为这个问题可能会解决您的问题:

它涉及使用以下方法强制临时ID在正常流量之前为永久性:
[上下文获取永久对象:[插入所有对象]错误:&error]

我遇到了这个问题,并对NSEntityDescription进行了分类以解决这个问题:

@implementation NSEntityDescription (PermanentID)
+ (id)insertNewPermanentObjectForEntityForName:(NSString *)entityName
                        inManagedObjectContext:(NSManagedObjectContext *)context
{
    id object = [self insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
    NSError *error;
    if (![context obtainPermanentIDsForObjects:[NSArray arrayWithObject:object] error:&error]) {
        NSLog(@"Permanent ID not given");
    }
    if (error) {
        NSLog(@"%@", error);
    }
    return object;
}

这里有更多关于的内容,但我已在此处复制了该类别,因此您不必点击浏览。

我遇到了此问题,并在NSEntityDescription上创建了一个小类别来解决此问题:

@implementation NSEntityDescription (PermanentID)
+ (id)insertNewPermanentObjectForEntityForName:(NSString *)entityName
                        inManagedObjectContext:(NSManagedObjectContext *)context
{
    id object = [self insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
    NSError *error;
    if (![context obtainPermanentIDsForObjects:[NSArray arrayWithObject:object] error:&error]) {
        NSLog(@"Permanent ID not given");
    }
    if (error) {
        NSLog(@"%@", error);
    }
    return object;
}
还有更多内容,但我已在此处复制了该类别,因此您无需点击浏览。

谢谢,在后台上下文中调用-OccainPermanentidForObjects:error:before-save:Help。谢谢,在后台上下文中调用-OccainPermanentidForObjects:error:before-save:helped。