Reputation: 1
Actually, I have implemented background sync call which stores data in a local database using CoreData. I am getting thousands of records for that, but the app crashes after some time and giving the error
EXC_BAD_ACCESS Code 1.
Maybe it happened due to NSManagedObjectContext
, not sure. Here is my code:
-(void)RestClient:(RestClient *)client didCompleteWithSuccess:(id)responseObject withLastModifiedDate:(NSString *)lastModifiedDate{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
@try {
if(responseObject!=nil){
NSError *error = nil;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
if (!error) {
int totalrecords = [[jsonResponse objectForKey:@"records"] intValue];
if(totalrecords>0){
NSManagedObjectContext * manageObjContext = [Common getBkgManagedObjectContext];
NSArray* rows = [jsonResponse objectForKey:@"rows"];
for(NSString* email in rows){
[NotifyEmails insertIntoNotifyEmails:email withManagedObjectContext:manageObjContext];
}
NSError *error = nil;
if (![manageObjContext save:&error]) {
NSLog(@"Data couldn't save: %@", [error localizedDescription]);
}
}
}
}
}@catch (NSException *exception) {
NSLog(@"exception in rest response");
NSLog(@"Error :: %@",exception);
}@finally {
[self finishOperation];
}
});
}
The NsmanagedObjectContext function :
- (NSManagedObjectContext *)getBkgManagedObjectContext {
NSManagedObjectContext *manageObjCtx;
NSPersistentStoreCoordinator *coordinator = [(EMAINTAINAppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];
if (coordinator != nil) {
manageObjCtx = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[manageObjCtx setPersistentStoreCoordinator:coordinator];
}
return manageObjCtx;
}
Upvotes: 0
Views: 232
Reputation: 8563
ManagedObjectContext
are not thread safe. It is vital to know for each context which thread it want to be run on. A context that was created with NSPrivateQueueConcurrencyType
comes bundled with a private thread that you can ONLY access with performBlock
or performBlockAndWait
(in other words the queue is PRIVATE). It is not safe to access the context on any other thread - even a background thread. The context is not attached to the thread that it was created on (as you seem to be assuming it will be), that was the behavior of NSConfinementConcurrencyType
which is now deprecated.
Upvotes: 1