Tag: nsmanagedobjectcontext

当两个单独的NSFetchRequests都完成时采取行动

我正在使用具有核心数据的远程数据库,当执行以下提取请求(取决于Internet连接)时,可能需要一些时间。 我想监视这两个请求,当它们完成时 – 无论成功还是失败 – 我想引发另一种方法。 FetchRequest 1: [self.managedObjectContext executeFetchRequest:fetchRequest1 onSuccess:^(NSArray *results) { //Succcess [self.refreshControl endRefreshing]; } onFailure:^(NSError *error) { [self.refreshControl endRefreshing]; }]; FetchRequest 2: [self.managedObjectContext executeFetchRequest:fetchRequest2 onSuccess:^(NSArray *results) { //Succcess [self.refreshControl endRefreshing]; } onFailure:^(NSError *error) { [self.refreshControl endRefreshing]; }]; 我想等到提取请求1和2都完成后再调用另一个方法。 我可以使用NSOperationQueue来监视这两个块吗? 如果不是的话,最好的方法是什么时候两个街区都已经完工?

核心数据并发队列风格MOC获取者线程安全

我直接从NSManagedObjectContext 文档直接感到困惑。 基于队列的托pipe对象上下文的setter方法是线程安全的。 你可以直接在任何线程上调用这些方法。 最大的问题是在ManagedObjectContext上的setter方法,而不是在这个上下文所拥有的ManagedObjects中。 还是两者兼而有之? 特别是如果对于私人队列MOC对象这样的话: [privateContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 线程安全无论执行这个线程的线程,但会像这样: [myPrivateQueueOwnedManagedObject setTitle:@"My Title]; 也是线程安全?,这个文档确实含糊不清,但我的理解是,这不会是线程安全的是正确的吗? 如何获取ManagedObjectContext中的属性(如询问persistentStoreCoordinator属性)是否是线程安全的? 我的理解是,它不会。 另外,一直以来我的理解是某些Managed Object属性(如objectID)是线程安全的,不需要使用performBlock:或performBlockAndWait来访问:受pipe对象上是否存在线程安全的其他任何属性?

performBlockAndWait创build死锁

我正在写一个执行一些CoreData的东西的函数。 我希望函数只有在所有的CoreData操作执行后才返回。 CoreData的东西包括在后台上下文中创build一个对象,然后在父上下文中做更多的事情: + (void) myFunction NSManagedObjectContext *backgroundContext = [DatabaseDelegate sharedDelegate].backgroundContext; [backgroundContext performBlockAndWait:^{ MyObject *bla = create_my_object_in:backgroundContext; [backgroundContext obtainPermanentIDsForObjects:[[backgroundContext insertedObjects] allObjects] error:nil]; [backgroundContext save:nil]; [[DatabaseDelegate sharedDelegate].parent.managedObjectContext performBlockAndWait:^{ [[DatabaseDelegate sharedDelegate].parent updateChangeCount:UIDocumentChangeDone]; // Do some more stuff NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperation:someOperation]; }]; }]; return; } 我希望返回只发生在[queue addOperation:someOperation] 。 这似乎工作大部分的情况下,但我有一个案件,当这个function从来没有返回。 它似乎是僵局,我怀疑这是因为performBlockAndWait 。 我的问题是: (1)有人可以解释为什么会发生这种僵局吗? […]

如何在Swift中正确地testing核心数据

目前已经有相当多的学科了,但是我还没有find一个适用于Swift(Xcode 6.2)的解决scheme。 要在Swift中testingCore Data支持的类,我生成了新的托pipe对象上下文,然后将其注入到我的类中。 //Given let testManagedObjectContext = CoreDataTestComposer.setUpInMemoryManagedObjectContext() let testItems = createFixtureData(testManagedObjectContext) as [TestItem] self.itemDateCoordinator.managedObjectContext = testManagedObjectContext //When let data = self.itemDateCoordinator.do() //Then XCTAssert(data.exists) 问题来自将testing中创build的MOC传递给正在执行的类。 因为实体类是命名空间,所以Core Data不会获取适当的ManagedObject子类,而是返回一个NSManagedObject集合。 循环或对这些对象进行任何操作(在你的类中将是一个testing项目的数组( [TestItem] )。 例如,违规类ItemDateCoordinator会执行这个循环(在从NSFetchRequest提取相关数据NSFetchRequest )“ for testItem in testItems { testItem.doPart(numberOfDays: 10) } 会导致: 致命错误:NSArray元素无法匹配Swift数组元素types 此外,我遇到了一个没有太多可靠答案的信息集合: 为了在创build实体时投射实体,我一直在使用Jesse的解决scheme,但是这不适用于更大范围的testing。 一个解决scheme已经发布在涉及到在运行时交换类的另一个问题上,但是这并不适用于我的实体inheritance。 在这种情况下是否有另一种方法来testing你的对象与核心数据? 你怎么做呢?

在CoreData保存之前识别哪些字段已经改变

//设置通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataChanged:) name:NSManagedObjectContextDidSaveNotification object:context]; //后来 – (void)dataChanged:(NSNotification *)notification{ NSDictionary *info = notification.userInfo; NSSet *insertedObjects = [info objectForKey:NSInsertedObjectsKey]; NSSet *deletedObjects = [info objectForKey:NSDeletedObjectsKey]; NSSet *updatedObjects = [info objectForKey:NSUpdatedObjectsKey]; 无论如何,从更新的对象确定哪些字段实际上被改变了吗? 谢谢,迈克尔

iOS RestKit无法将本地实体保存到数据库

我正在使用RestKit 0.20来parsingJSON数据并保存到数据库。 这是一个映射实体SchoolClass,由RestKit处理,并保存罚款。 我有另一个名为MyClass的实体,它存储我select的类。 这个只在设备上是本地的。 这里是我创build并保存MyClass实体的代码 NSManagedObjectContext *managedObjCtx = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext; MyClass* course = [managedObjCtx insertNewObjectForEntityForName:@"MyClass"]; .. set the data for course here NSError *executeError = nil; if(![managedObjCtx save:&executeError]) { NSLog(@"Failed to save to data store"); } 这是初始化托pipe数据存储的代码 // Initialize managed object store NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]; objectManager.managedObjectStore […]

iPhone的iOS如何合并核心数据NSManagedObjectContext?

我试图在后台下载一些JSON对象,并做了相当多的multithreading。 一旦操作完成,我注意到这个断言失败了: NSAssert([user.managedObjectContext isEqual:[AppUser managedObjectContext]],@"Different contexts"); 如何将更改合并到[AppUser managedObjectContext]定义的主要上下文中?

核心数据pipe理对象上下文devisebuild议

我们正在研究一个企业级的应用程序,它将存储数以万计的核心数据对象,我们在几个方面都有问题。 我们的应用程序有几个独立的系统,在需要时对数据进行操作。 这些系统包括项目的发现,项目的加载,同步和UI显示。 如果我们正确地devise我们的软件,由于不同的系统修改相同的对象,应该有很less的甚至没有合并冲突。 每个系统都有自己的操作队列,全部在后台执行。 我们希望在后台保留所有对象的创build和修改,以最大限度地减lessUI性能问题,特别是在初始阶段,可能会从服务器上的数据创build数千个对象。 在这里我们遇到了几个与我们的各种devise尝试的问题。 在这些上升过程中巨大的内存消耗,以及所有上下文和子上下文的错误编排,导致死锁和崩溃。 我们尝试了以下devise: 一个拥有一个子NSMainQueueConcurrencyType上下文的根NSPrivateQueueConcurrencyType托pipe对象上下文。 UI获取的结果控制器使用此子上下文从中获取结果。 从NSMainQueueConcurrencyType子上下文中,我们创build了一个NSPrivateQueueConcurrencyType子上下文,我们称之为“savingContext”,每个后台操作创build了“savingContext”的子上下文,做了修改,最后做了我们所谓的“深度保存”保存到顶部。 我们最初select这种devise,不必处理来自许多不同的子上下文的NSManagedObjectContextDidSaveNotification通知。 我们将每个调用都包装到NSPrivateQueueConcurrencyType上下文中,并使用performBlockAndWait:来访问对象。 在function上,这个devise进行。 所有更改和插入已保存到持久性存储,并更新了UI的更改。 这个,介绍了两个问题。 其中一个是laggy UI,因为合并后的更改通过NSMainQueueConcurrencyType子上下文,更重要的是,在启动期间非常高的内存使用率。 由于无法在上下文上recursion调用reset (因为主UI子上下文也存在)和/或缺less何时调用refreshObject:mergeChanges: 所以我们走了一条不同的路 有两个顶级上下文链接到持久性存储协调器,一个用于保存子上下文的NSMainQueueConcurrencyType和一个用于UI显示的NSMainQueueConcurrencyType 。 NSMainQueueConcurrencyType侦听来自主NSPrivateQueueConcurrencyType上下文的NSManagedObjectContextDidSaveNotification通知,并将它们合并到主线程中。 每个后台操作都创build主NSPrivateQueueConcurrencyType上下文的子上下文,也使用私有队列并发types,做它所做的事情,recursion地执行“深度保存”,在当前上下文执行保存,深度保存到其上下文的recursion调用父母,调用当前上下文重置并再次保存。 这样我们可以避免内存问题,因为创build的对象在保存后快速释放。 但是,通过这种devise,我们遇到了很多问题,例如NSInternalInconsistencyException , NSInternalInconsistencyExceptionexception和获取的结果控制器不更新UI,尽pipe保存NSMainQueueConcurrencyType上下文的通知。 这也会导致UI中的初始加载时间减慢很多。 在之前的devise中,抓取的结果控制器返回结果的速度非常快,而这会阻塞UI几秒钟,直到视图加载(我们在viewDidLoad初始化抓取的结果控制器)。 我们已经尝试了许多中间devise,但都围绕相同的问题,无论是非常高的内存使用率,获取的结果控制器不更新UI或死锁和NSInternalInconsistencyExceptionexception。 我真的感到沮丧。 我不得不觉得,我们的devise显然是复杂的,应该是相当简单的事情,只是我们不了解一些基本的东西正在杀死我们。 那么你们会build议什么? 你会根据我们的情况推荐什么样的安排? 我们应该如何在不同的线程中pipe理不同的上下文? 释放插入的对象和重置上下文的最佳实践? 避免死锁? 所有的帮助,将在此时赞赏。 我也看到了MagicalRecords类别的build议。 是否推荐? 我们已经投入使用核心数据types,使用MR迁移有多困难?

iOS5 NSManagedObjectContext并发types,它们是如何使用的?

目前有关新的NSManagedObjectContext并发types的文献似乎有点稀疏。 除了WWDC 2011 vids和其他一些我一路上拿到的信息之外,我仍然很难理解每种并发types的使用方式。 以下是我如何解释每种types。 如果我理解错误,请纠正我的错误。 NSConfinementConcurrencyType 这种types在过去几年一直是常态。 每个线程屏蔽MOC。 因此,如果线程MOC想要通过保存消息合并来自线程B MOC的数据,则线程A将需要订阅线程B的MOC保存通知。 NSPrivateQueueConcurrencyType 每个MOC树(父&子MOC)共享相同的队列,无论每个线程在哪个线程上。 所以每当发送来自这些上下文的保存消息时,它都被放在专门为这个MOC树所做的专用提示中。 NSMainQueueConcurrencyType 还是被这个弄糊涂了。 从我所收集的类似NSPrivateQueueConcurrencyType中,只有专用队列在主线程上运行。 我读到这对于与MOC的UI通信是有利的,但是为什么呢? 为什么我会select这个NSPrivateQueueConcurrencyType? 我假设,因为NSMainQueueConcurrencyType在主线程中执行,这是否不允许后台进程? 这不是不使用线程?

CoreData无法完成错误

我有一个非常恼人的问题,我似乎无法修复。 当我发送一条消息被保存到核心数据时,我有一个视图,当它完成时,它向数据库询问一个随机消息(句子),并将其保存到数据库中的另一行。 如果我做了最后一部分硬编码,没有从数据库中获取数据,它的工作都很好,但是一旦我从数据库中获取随机行,它就会变得疯狂。 在我的AppDelegate.m中: – (void)save { NSAssert(self.context != nil, @"Not initialized"); NSError *error = nil; BOOL failed = [self.context hasChanges] && ![self.context save:&error]; NSAssert1(!failed,@"Save failed %@",[error userInfo]); } – (NSString*)selectRandomSentence { NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentences" inManagedObjectContext:self.managedObjectContext]; [request setEntity:entity]; NSError *error = nil; NSUInteger count = [self.context countForFetchRequest:request […]