开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜