我有以下对象树:
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...
>用户可以为一个项目分配一个组.所有后代都被设置为该项目.
>这会锁定主线程,所以我使用NSOperations.
>我正在使用Apple批准的这种方法,看NSManagedobjectContextDidSaveNotification并合并到主要的上下文中.
问题
我的保存已经失败,出现以下错误:
保存前无法处理挂起的更改. 100次尝试后,上下文仍然很脏.通常这个递归的脏污是由一个坏的验证方法,-willSave或通知处理程序引起的.
我试过的
我已经把我的应用程序的所有复杂性都消除掉了,并且做了我能想到的最简单的项目.并且错误仍然发生.我试过了:
>将队列上的最大操作数设置为1或10.
>调用refreshObject:mergeChanges:在NSOperation子类的几个点.
>在受管对象上下文中设置合并策略.
>建立和分析.它变空了
我的问题
没有我的应用程序崩溃,我如何在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抱怨.
解决方法
startTest从一个按钮调用(是IBAction,假设按钮点击)在主线程上
>您的for循环使用初始化程序trainGroup创建一个JGMakeRelationship对象:withProject:(这应该称为init,并且可能调用super,但这不会导致此问题).
>在主线程中,在操作中创建一个新的托管对象上下文.
>现在操作队列从工作线程调用操作“main”方法(在这里放置一个断点,你会看到它不在主线程上).
>您的应用程序变得繁荣,因为您已经从与其创建的线程不同的线程访问了受管对象上下文.
解:
在操作的main方法中初始化托管对象上下文.
原文地址:https://www.jb51.cc/java/122978.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。