我在CoreData和Parent-Child MOC中遇到此問題:將對象添加到子MOC時,保存它們並保存父MOC所有對象都將其屬性重置爲默認值。父MOC獲取來自兒童MOC的空數據的更改
我在這裏粘貼了兩個MOC的日誌,特別是這些日誌中的「stringAttribute」和「date」屬性被重置。
我到處搜索這個問題,但我沒有找到任何東西,我也看了很多親子MOC的實現,但我無法弄清楚我做錯了什麼。
在此先感謝!
下面的代碼片段:
我一些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;
[...]
})
)}
UPDATE
我已經應該提到的是,managedObject
加入上下文通過上下文零初始化。然後在致電saveContext:
之前,我檢查是否存在object.managedObjectContext
,如果沒有,那麼我將其設置爲[self managedObjectContext]
,即使用上述方法創建的那個。因此,要麼如果managedObject
與零上下文創建,創建的或具有:
+ (id)newObjectForInsertion
{
return [[self alloc] initWithEntity:[self entityDescription] insertIntoManagedObjectContext:[DKDatabaseManager defaultManager].managedObjectContext];
}
相關managedObjectContext是在同一個隊列(NSMainQueueConcurrencyType)。
否則,如果managedObject
與+newObjectForInsertion
所有saveContext:
併發鏈回報是,所有的變化都傳遞給父上下文的創建。
我不知道它是一個錯誤還是CoreData應該工作的方式。
蘋果開發者論壇同樣的問題:
https://devforums.apple.com/thread/174677?tstart=90
你確定它是日誌中的同一個實體嗎? dateAttribute不重置,但完全不同。 – eofster
是的。它應該是相同的,因爲傳遞的id是相同的('entity:Entity; id:0x9582d40')。 date屬性重置爲.xcdatamodeld中設置的默認值。應該使用'performBlockAndWait:'安全地傳遞更改,所以我不認爲是objectID的問題。我沒有完全確定BTW – Pencildrummer