Error in batch updating into core data with the thread
I am facing an issue in updating to core data using batch updating on a background thread. In the below code I am using main thread to notify user with a progress view and a string which calls a method in appdelegate. But if I am getting bad access error in the NSEntity line in random number of data where I have thousands of objects to update.if I uncomment the NSLOG i have indicated below there is no error, or if i comment the main thread no error, or if I dont update through batch instead if I use bulk update then also no error. IF i comment autorelease pool also the error is appearing. Will some body help me on this please.
Thanks in advance,
Cheers, Shravan
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
NSUInteger iterator = 1;
for (int i = 0; i < totalNo; i++) {
NSDictionary *alertResult = [[alertResultList objectAtIndex:i] retain];
if (alertResult == nil) {
continue;
}
//managedObjectContext = [appDelegate.managedObjectContext retain];
NSLog(@"Object Count:%u", [[managedObjectContext insertedObjects]count]);
AlertResult *result = (AlertResult *)[NSEntityDescription
开发者_开发百科 insertNewObjectForEntityForName:@"AlertResult"
inManagedObjectContext:managedObjectContext];
[result setUserName:@"A"];
iterator++;
//When count reaches max update count we are saving and draining the pool and resetting the pool
if (iterator == kUploadCount) {
if ([self update] == NO) {
// If unable to update Alert results in the Core Data repository, return
// a custom status code.
statusCode = -1;
}
[managedObjectContext reset];
[tempPool drain];
tempPool = [[NSAutoreleasePool alloc] init];
iterator = 0;
}
//Adding code to change the display string for the lock view to notify user
float count1 = (float)(counter/totalAlerts);
counter = counter + 1.0f;
NSString *dispStr = [NSString stringWithFormat:@"%f",count1];//[NSString stringWithFormat:@"Loading %d out of %d alerts",(i+1),totalAlerts];
NSString *dispMess = [NSString stringWithFormat:@"Alerts %d of %d",(i+1),totalNo];
[self performSelectorOnMainThread:@selector(changeLockScreenMessageWith:) withObject:[NSArray arrayWithObjects:dispStr,dispMess, nil] waitUntilDone:YES];
//NSLog(@"count"); /* If I uncomment this line code runs fine */
[alertResult release];
alertResult = nil;
}
//If count is inbetween the update limit we are updating and we are draining the pool
if (iterator != 0) {
if ([self update] == NO) {
// If unable to update Alert results in the Core Data repository, return
// a custom status code.
statusCode = -1;
}
[managedObjectContext reset];
//[tempPool drain];
}
//Out side the previous method
- (BOOL)update {
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"%@", [error userInfo]);
return NO;
}
return YES;
}
The most likely cause of the kind of crash you're describing is using your managedObjectContext
across threads. managedObjectContext
is not thread-safe. You must create a new MOC for each thread. I assume managedObjectContext
is an ivar; you should never access your ivars directly like this (except in init and dealloc). Always use an accessor to handle memory management for you.
The reason NSLog
makes it crash is because NSLog
dramatically changes the timing of this function, and you have a race condition.
精彩评论