Reputation: 1692
Here is the code snippet of my core data operation . It works fine most of the time. But now when I added core data debugging argument to see if all the core data calls are fine with respect to multithreading Core Data Concurrency Debugging , I see a crash on the line [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
}
There is only one main queue context attached to persistent store coordinator . This one is used as parent for each child context that is created for a core data operation .
(void)readAllModelObjects is called from a background thread as expected .
I got below error from core data
CoreData`+[NSManagedObjectContext _
_Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:
Any hints / suggestions will definitely help me in figuring out the crash , please help .
Upvotes: 1
Views: 1199
Reputation: 8563
When you change values of a managedObject those changes are not saved until the context is saved. Once you save the context, the context either writes to disk or pushes it up to its parent context. This is a way to have a few changes that are all done as one unit - in database speak it would be called a transaction. reset
undoes those changes. So just like changing object needs to be done on the correct thread, reset
which undoes the changes, needs to be done on the correct thread.
In your case, there is no need to call reset
at all because you haven't changed anything to context. The context doesn't have any changes that would be undo by a reset
. If you would want to call reset
you would have to do inside the performBlockAndWait
.
TD;DR : [context reset]
is not thread-safe and must be done from the correct thread.
Upvotes: 2