我在CoreData和父-子MOC中遇到了这个问题:当向子MOC添加对象、保存对象和保存父MOC时,所有对象都会将它们的属性重置为defaultValue。
我在这里粘贴了来自两个MOC的日志,特别是在这些日志中重置的"stringAttribute“和"date”属性。
我到处寻找这个问题,但我什么也没发现,我也看了很多父母-孩子MOCs的实现,但我不知道我做错了什么。
提前感谢!
下面是代码片段:
我将一些NSManagedObject添加到主上下文中,然后使用saveContext:方法进行保存。
// Another singleton method
- (void)anotherMethod
{
[...]
[self.managedObjectContext insertObject:managedObject];
NSError *error;
save = [self saveContext:&error];
[...]
}
// Database manager singleton method
- (BOOL)saveContext:(DKError *__autoreleasing *)error
{
__block BOOL save = NO;
__block NSError *internalError;
[self.managedObjectContext performBlockAndWait:^{
internalError = nil;
[self.managedObjectContext log]; // See log 1.1 below
save = [self.managedObjectContext save:&internalError];
if (!save) {
NSLog(@"Error saving data in main context");
} else {
[self.managedObjectContext.parentContext performBlock:^{
internalError = nil;
save = NO;
[self.managedObjectContext.parentContext log]; // See log 1.2 below
save = [self.managedObjectContext.parentContext save:&internalError];
if (!save) {
NSLog(@"Error saving data to disk!");
}
}];
}
}];
*error = [DKError errorWithNSError:internalError]; // Custom error class
return save;
}父-子上下文代码
- (NSManagedObjectContext *)writerObjectContext
{
if (_writerObjectContext != nil)
return _writerObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_writerObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_writerObjectContext setPersistentStoreCoordinator:coordinator];
}
return _writerObjectContext;
}
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setParentContext:[self writerObjectContext]];
return _managedObjectContext;
}日志1.1
Inserted objects:
{(
<Entity: 0x9595120> (entity: Entity; id: 0x9582d40 <x-coredata:///Entity/t24D0F98B-CB94-41D3-BEDD-79913454A9152> ; data: {
[...]
dateAttribute = "2013-07-12 10:36:31 +0000";
stringAttribute = ricercaEntity;
[...]
})
)}日志1.2
Inserted objects:
{(
<Entity: 0xb53ce80> (entity: Entity; id: 0x9582d40 <x-coredata:///Entity/t24D0F98B-CB94-41D3-BEDD-79913454A9152> ; data: {
[...]
dateAttribute = "2013-01-05 11:00:00 +0000";
stringAttribute = nil;
[...]
})
)}更新
我应该提到添加到上下文中的managedObject是用上下文nil初始化的。然后,在调用saveContext:之前,我检查是否存在object.managedObjectContext,如果它为零,则将其设置为[self managedObjectContext],即用上面的方法创建的[self managedObjectContext]。所以,如果managedObject是用nil上下文创建的,或者是用以下方法创建的:
+ (id)newObjectForInsertion
{
return [[self alloc] initWithEntity:[self entityDescription] insertIntoManagedObjectContext:[DKDatabaseManager defaultManager].managedObjectContext];
}关联的managedObjectContext位于同一个队列(NSMainQueueConcurrencyType)上。
否则,如果managedObject是用+newObjectForInsertion创建的,则所有saveContext:并发链返回YES,所有更改都传递给父上下文。
我不知道是bug还是CoreData的工作方式。
在Apple Developer论坛上也存在同样的问题:
发布于 2013-07-12 11:26:22
您应该使用concurrencyType插入上下文:
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];另外,设置合并策略
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];NSMergeByPropertyObjectTrumpMergePolicy此策略将持久存储对象的版本与当前内存中版本之间的冲突合并起来,优先处理内存中的更改。合并由单个属性进行。对于已在外部源和内存中更改的属性,内存中的更改大于外部的更改。
顺便说一下,我发现了类似的问题:strange-behavior-when-using-child-parent-nsmanagedobjectcontext查看使用通知合并的可接受的答案。
https://stackoverflow.com/questions/17613510
复制相似问题