问题描述
我的问题是这样的。我想异步保存到磁盘。设置核心数据堆栈的代码如下所示。
My problems goes like this. I want to async saves to disk. The code to setup core data stack looks like this.
- (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]'
另一方面,这样的堆栈设置效果很好:
On the other hand stack setup like this works perfectly well:
- (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和一些用于管理它的其他对象。问题是,为什么此获取会受到影响,而应用程序之前使用相同参数进行的计数却能同时工作两次?
Database has inside one DataObject and some additional objects used to manage it around. The question is, why this fetch is affected, while a count that app does before with same parameters works both times?
推荐答案
它看起来CoreData内部的某些东西变得不一致,好像您还在处理错误的合并通知一样(使用父级子级时不必这样做,也不应尝试!)。不幸的是,如果没有完整的堆栈跟踪信息,将很难重建这里发生的事情。
It looks like something inside CoreData is getting inconsistent, as if you were also processing a bad merge notification (which you shouldn't have to do when using parent child, and should not attempt!). Without a full stack trace unfortunately it would be pretty difficult to reconstruct what was going on here.
但是我看不到原因在dispatch_once块内设置您的主队列上下文。上下文很便宜,没有理由每次都不需要产生新的子上下文-这是使用它们的推荐方法。 是:
However I don't see a reason to set up your main queue context inside the dispatch_once block. Contexts are made to be cheap, there is no reason not to produce a new child context every time you need one - and that is the recommended way to use them. An NSManagedObjectContextis:
并带有:
嵌套上下文使采用
比以往任何时候都更加重要。 传递指挥棒的方法是访问上下文(通过将上下文
从一个视图控制器传递到下一个视图控制器),而不是直接从应用程序委托检索它
。
Nested contexts make it more important than ever that you adopt the "pass the baton" approach of accessing a context (by passing a context from one view controller to the next) rather than retrieving it directly from the application delegate.
如果要查看设置父子上下文并使用队列限制的简单示例:
If you want to see a simple example of setting up parent-child contexts and using queue confinement:https://github.com/quellish/QueuedCoreData
这篇关于CoreData崩溃,并将主队列上下文设置为专用队列上下文的子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!