多线程 – 为什么在NSOperation子类中修改Core Data关系时,我的
背景
我有以下对象树: Name Project Users nil John nil Documents nil Acme Project Acme Project <--- User selects a project Proposal.doc Acme Project 12:32-12:33 Acme Project 13:11-13:33 Acme Project ...thousands more entries here... >用户可以为一个项目分配一个组.所有后代都被设置为该项目. 问题 我的保存已经失败,出现以下错误: 保存前无法处理挂起的更改. 100次尝试后,上下文仍然很脏.通常这个递归的脏污是由一个坏的验证方法,-willSave或通知处理程序引起的. 我试过的 我已经把我的应用程序的所有复杂性都消除掉了,并且做了我能想到的最简单的项目.并且错误仍然发生.我试过了: >将队列上的最大操作数设置为1或10. 我的问题 没有我的应用程序崩溃,我如何在NSOperation中设置关系?当然这不是Core Data的限制吗?它可以? 代码 下载我的项目:http://synapticmishap.co.uk/CDMTTest1.zip 主控制器 @implementation JGMainController -(IBAction)startTest:(id)sender { NSManagedObjectContext *imoc = [[NSApp delegate] managedObjectContext]; JGProject *newProject = [JGProject insertInManagedObjectContext:imoc]; [newProject setProjectName:@"Project"]; [imoc save]; // Make an Operation Queue NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue setMaxConcurrentOperationCount:1]; // Also crashes with a higher number here (unsurprisingly) NSSet *allTrainingGroupsSet = [imoc fetchAllObjectsForEntityName:@"TrainingGroup"]; for(JGTrainingGroup *thisTrainingGroup in allTrainingGroupsSet) { JGMakeRelationship *makeRelationshipOperation = [[JGMakeRelationship alloc] trainGroup:[thisTrainingGroup objectID] withProject:[newProject objectID]]; [queue addOperation:makeRelationshipOperation]; makeRelationshipOperation = nil; } } // Called on app launch. -(void)setupLotsOfTestData { // Sets up 10000 groups and one project } @end 进行关系操作 @implementation JGMakeRelationshipOperation -(id)trainGroup:(NSManagedObjectID *)groupObjectID_ withProject:(NSManagedObjectID *)projectObjectID_ { appDelegate = [NSApp delegate]; imoc = [[NSManagedObjectContext alloc] init]; [imoc setPersistentStoreCoordinator:[appDelegate persistentStoreCoordinator]]; [imoc setUndoManager:nil]; [imoc setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeChanges:) name:NSManagedObjectContextDidSaveNotification object:imoc]; groupObjectID = groupObjectID_; projectObjectID = projectObjectID_; return self; } -(void)main { JGProject *project = (JGProject *)[imoc objectWithID:projectObjectID]; JGTrainingGroup *trainingGroup = (JGTrainingGroup *)[imoc objectWithID:groupObjectID]; [project addGroupsAssignedObject:trainingGroup]; [imoc save]; trainingGroupObjectIDs = nil; projectObjectID = nil; project = nil; trainingGroup = nil; } -(void)mergeChanges:(NSNotification *)notification { NSManagedObjectContext *mainContext = [appDelegate managedObjectContext]; [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES]; } -(void)finalize { appDelegate = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; imoc = nil; [super finalize]; } @end @implementation NSManagedObjectContext (JGUtilities) -(BOOL)save { // If there's an save error,I throw an exception } @end 数据模型 更新1 我已经尝试了一些,即使没有合并,仍然抛出异常.修改关系后,只需将管理对象上下文保存在另一个线程就足够了. 我有一个共享的持久性商店协调员与应用程序代表.我已经尝试为线程使用与数据存储相同的URL创建一个单独的NSPersistentStoreCoordinator,但是Core Data抱怨. 我很乐意提供关于如何使线程的协调者的建议.核心数据文件提到有一种方法,但我看不到如何. 解决方法
你正在跨越在CoreData中非常糟糕的流(在这种情况下是线程).这样看看:
startTest从一个按钮调用(是IBAction,假设按钮点击)在主线程上 解: 在操作的main方法中初始化托管对象上下文. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |