以下是我的核心数据操作的代码段。它大部分时间都可以正常工作。但是现在当我添加核心数据调试参数以查看所有核心数据调用是否与多线程Core Data Concurrency Debugging相关时,我看到线路崩溃[contexts reset];
- (void)readAllModelObjects {
NSFetchRequest * fr = [NSFetchRequest ....]
NSManagedObjectContext * context = [selg getChildContext];
[context performBlockAndWait:^{
NSArray * resultArray = [context executeFetchRequest:fr error: nil ];
NSArray * nonCoreDataModelObjectsArray = [self parseCoreDataObjectsToModel: resultArray];
_memberResultArray = nonCoreDataModelObjectsArray ;
}];
[context reset]; // This is the line it crashes .
}
- (NSManagedObjectContet *)getChildContext {
NSManagedObjectContext * privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
privateContext.parentContext = [self mainQueueManagedObjectContext];
return privateContext ;
}
- (NSArray * )parseCoreDataObjectsToModel:(NSArray *)cdObjectsArray {
// creates and initializes the model objects array (non managed object class objects ) from core data objects
// return this array
}
持久性存储协调器只附加一个主队列上下文。这个用作为核心数据操作创建的每个子上下文的父级。
(void)readAllModelObjects按预期从后台线程调用。
我从核心数据中得到以下错误
CoreData`+[NSManagedObjectContext _
_Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:
任何提示/建议肯定会帮助我搞清楚崩溃,请帮忙。
答案 0 :(得分:1)
更改managedObject的值时,在保存上下文之前不会保存这些更改。保存上下文后,上下文将写入磁盘或将其推送到其父上下文。这是一种方法,可以作为一个单元进行一些更改 - 在数据库中说它将被称为事务。 reset
撤消这些变化。因此,就像需要在正确的线程上更改对象一样,reset
撤消更改,需要在正确的线程上完成。
在您的情况下,根本不需要调用reset
,因为您没有将任何内容更改为上下文。上下文没有任何可由reset
撤消的更改。如果您想要致电reset
,则必须在performBlockAndWait
内进行。
TD; DR :[context reset]
不是线程安全的,必须从正确的线程完成。