我的问题是这样的。我想异步保存到磁盘。设置核心数据堆栈的代码如下所示。
- (NSManagedObjectContext *)managedObjectContext {
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSManagedObjectContext *privateMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateMOC setPersistentStoreCoordinator:coordinator];
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[__managedObjectContext setParentContext:privateMOC];
});
return __managedObjectContext;
}
当我执行这样的抓取时:
NSMutableArray *result = [NSMutableArray array];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:[DataObject entityName]
inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
[request setPredicate:[NSPredicate predicateWithFormat:@"SUBQUERY(threadEntities, $emp, $emp.thread = %@).@count>0 AND tags.@count!=0", self, nil ]];
[request setPropertiesToFetch:@[@"creationDate", @"data"]];
[request setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]]];
NSError *error = nil;
[result addObjectsFromArray:[self.managedObjectContext executeFetchRequest:request error:&error]];
它崩溃了这个错误:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 375961053 beyond bounds [0 .. 7]'
另一方面,像这样的堆栈设置非常有效:
- (NSManagedObjectContext *)managedObjectContext {
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
});
return __managedObjectContext;
}
数据库内部有一个DataObject,还有一些用于管理它的附加对象。问题是,为什么这个提取会受到影响,而app之前用相同参数执行的计数会同时工作?
答案 0 :(得分:0)
看起来CoreData内部的东西变得不一致,好像你也处理了一个错误的合并通知(使用父子时你不应该这样做,而且不应该尝试!)。遗憾的是,没有完整的堆栈跟踪,重建这里发生的事情将非常困难。
但是我没有看到 reason 在dispatch_once块中设置主队列上下文。上下文变得便宜,没有理由不在每次需要时生成新的子上下文 - 这是使用它们的推荐方法。 NSManagedObjectContext是:
NSManagedObjectContext的实例表示单个“对象” 空间“或应用程序中的便笺簿。它的主要责任是 管理托管对象的集合。这些对象组成一个组 表示内部一致视图的相关模型对象 一个或多个持久性商店。
使用parent-child:
在上下文中保存更改时,仅提交更改 “一个存储起来。”如果您保存子上下文,则会将更改推送到其中 家长。直到这些更改才会保存到持久性存储中 根上下文已保存。 (根管理对象上下文是其中的一个 parent是nil。)此外,父母不会从中提取更改 孩子们节省之前。如果需要,您必须保存子上下文 最终要做出改变。
嵌套上下文比以往任何时候都更重要 “传递接力棒”访问上下文的方法(通过传递上下文 从一个视图控制器到下一个视图控制器而不是检索它 直接来自应用程序代理。
如果您想查看设置父子上下文和使用队列限制的简单示例: https://github.com/quellish/QueuedCoreData