好吧,这让我发疯了。
我有两个使用 UImanageddocument 的线程,一个在用户进行选择的主上下文中,具有自己的 moc 的后台线程根据时间戳将数据与服务器同步。
一切似乎都运行良好,但是当我: 1. 在主上下文中添加一个对象 2. 在后台同步 3. 从后台保存 4. 尝试再次更改同一个对象,现在从主上下文 - 主线程
我得到一个 NSMergeConflict
我将包含我的一些代码,不包括很多不相关的代码,向您展示我如何初始化上下文,希望有人能启发我。我知道核心数据在这些领域很棘手。
在主线程上(在 applicationdidfinishloadingwithoptions 中):
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; //get the default user documents folder
url = [url URLByAppendingPathComponent:DATABASENAME];
UIManagedDocument *doc = [[UIManagedDocument alloc] initWithFileURL:url];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
doc.persistentStoreOptions = options;
[doc.managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
self.database=doc;
self.mainManagedObjectContext=self.database.managedObjectContext;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDataModelChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.database.managedObjectContext];
然后:
- (void)handleDataModelChange:(NSNotification *)note
{
[self save];
}
-(void) save
{
[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
batch_save=!success;
NSLog(@"save success %d",success);
}];
}
在后台线程上:
dispatch_queue_t fetchQ = dispatch_queue_create("syncing list", NULL);
dispatch_async(fetchQ, ^ // *********** BACKGROUND THREAD ***********
{
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *backgroundMOC2;
backgroundMOC2=[[NSManagedObjectContext alloc] init];
[backgroundMOC2 setPersistentStoreCoordinator:delegate.mainManagedObjectContext.persistentStoreCoordinator];
[backgroundMOC2 setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[delegate.mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[[NSNotificationCenter defaultCenter] addObserver:delegate.mainManagedObjectContext selector:@selector(mergeChangesFromContextDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2];
** pseudo-code:
perform fetch request from CD
submit data to server with POST request (synchronously)
retrieve JSON reply from server
update what's needed in CD objects
** end of pseudo code
[backgroundMOC2 save:nil];
[[NSNotificationCenter defaultCenter] removeObserver:delegate.mainManagedObjectContext name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2];
});
dispatch_release(fetchQ);
我尝试了所有类型的合并策略常量都无济于事。
我得到了这个,并且文件没有保存:
冲突列表 = ("NSManagedObject (0x119aea80) 的 NSMergeConflict (0x1a9ee1e0),objectID 为 '0x9dcec90',oldVersion = 10 和 newVersion = 11,旧对象快照 = {\n displayName = \"\";\n machineName = KIYGRDRTTDVLTQB;\n note = \"\";\n 产品 = \"0x11967ab0 \";\n 公开 = 1;\n 发布 = 1;\n 数量 = 3;\n 注册地址 = \"\";\n 注册地址 = \"\ ";\n registeredToNote = \"\";\n status = \"ON REGISTRY\";\n upDate = \"2013-03-07 10:22:01 +0000\";\n wishList = \"\ ";\n} 和新缓存行 = {\n displayName = \"\";\n machineName = KIYGRDRTTDVLTQB;\n note = \"\";\n product = \"0x1a9ee3d0 \";\n public = 1 ;\n 已发布 = 1;\n 数量 = 3;\n registeredTo = \"\";\n registeredToEmail = \"\";\n registeredToNote = \"\";\n status = \"ON REGISTRY\";\n upDate = \" 2013-03-07 10:22:03 +0000\";\n wishList = \"\";\n}" ); }
顺便说一句,我在新旧对象之间看到的唯一区别是指向“产品”的指针。这可能是我的问题吗?
另一个可能的线索是,这仅在添加新对象时发生,并且仅在后台同步发生之后发生。如果我停止应用程序并重新加载它(重新加载持久存储),我现在可以毫无问题地编辑该现有对象,并根据我的喜好多次同步它而没有问题。
多谢你们