我有一个多线程应用程序,我需要将私有上下文合并到主上下文,而主上下文又连接到持久存储控制器。
我还需要创建不受管理的临时对象(直到我后来决定管理它们)。
首先,我尝试按如下方式创建我的临时对象;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:myMainQueueContext];
User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
在决定是否保留该对象后,我就简单了;
[privateContext insertObject:user];
在我使应用程序多线程之前,这很好用,但是现在在稍微拆开东西并通过子/父上下文添加多线程并发之后,结果并不像预期的那样。
通过查看上下文的“registeredObjects”,我可以看到我创建的,现在插入的用户是在 privateContext 中管理的。保存后,mainContext 会发生相应的变化,我可以看到它 hasChanges 并且在 registeredObjects 中现在有一个对象。
但仔细观察 mainContext 中的 THAT registeredObject,发现它已被清空。没有内容。根据类型,所有属性都是 nil 或 0。因此,人们会认为这可能是因为 objectId 不一样......但它是 ;( 它是同一个对象。但没有内容。
我试图在这里的另一篇文章中就这个问题提出一些意见,但没有成功。
无论如何,我终于通过改变我创建对象的方式来让事情发挥作用。
User* user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:privateContext];
突然间,我的子对象被合并到 mainContext 而没有丢失它们的内容,原因我不知道,但不幸的是,这也导致我不能再创建临时的非托管对象......;(我读到 Marcus Zarra 支持我的第一种方法是创建非托管对象,但这不适用于我的多线程应用程序中的合并上下文...
期待任何想法和想法——我是唯一一个试图在异步工作线程中创建临时对象的人吗,我只想管理/合并它们的子集到 mainContext?
编辑
具体代码显示什么是有效的,更重要的是什么是无效的;
//Creatre private context and lnk to main context..
NSManagedObjectContext* privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
//Link private context to main context...
privateManagedObjectContext.parentContext = self.modelManager.mainManagedObjectContext;
[privateManagedObjectContext performBlock:^()
{
//Create user
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:self.modelManager.mainManagedObjectContext];
User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
[user setGuid:@"123123"];
[user setFirstName:@"Markus"];
[user setLastName:@"Millfjord"];
[privateManagedObjectContext insertObject:user];
//Debug before we start to merge...
NSLog(@"Before private save; private context has changes: %d", [privateManagedObjectContext hasChanges]);
NSLog(@"Before private save; main context has changes: %d", [self.modelManager.mainManagedObjectContext hasChanges]);
for (NSManagedObject* object in [privateManagedObjectContext registeredObjects])
NSLog(@"Registered private context object; %@", object);
//Save private context!
NSError* error = nil;
if (![privateManagedObjectContext save:&error])
{
//Oppps
abort();
}
NSLog(@"After private save; private context has changes: %d", [privateManagedObjectContext hasChanges]);
NSLog(@"After private save; main context has changes: %d", [self.modelManager.mainManagedObjectContext hasChanges]);
for (NSManagedObject* object in [privateManagedObjectContext registeredObjects])
NSLog(@"Registered private context object; %@", object);
for (NSManagedObject* object in [self.modelManager.mainManagedObjectContext registeredObjects])
NSLog(@"Registered main context object; %@", object);
//Save main context!
[self.modelManager.mainManagedObjectContext performBlock:^()
{
//Save main context!
NSError* mainError = nil;
if (![self.modelManager.mainManagedObjectContext save:&mainError])
{
//Opps again
NSLog(@"WARN; Failed saving main context changes: %@", mainError.description);
abort();
}
}];
}];
以上不起作用,因为它创建了一个临时对象,然后将其插入到上下文中。然而,这个轻微的 mod 让事情变得正常,但阻止我拥有临时对象......;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:self.modelManager.mainManagedObjectContext];
User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:privateManagedObjectContext];
因此,我想知道;有什么不同?显然,肯定有一些区别,但我不明白。