Ошибка пакетного обновления данных ядра с потоком - PullRequest
0 голосов
/ 24 августа 2011

У меня проблема с обновлением основных данных с помощью пакетного обновления в фоновом потоке.В приведенном ниже коде я использую основной поток для уведомления пользователя с представлением прогресса и строкой, которая вызывает метод в appdelegate.Но если я получаю ошибку неверного доступа в строке NSEntity в случайном количестве данных, где у меня есть тысячи объектов для обновления. Если я раскомментирую NSLOG, который я указал ниже, то ошибки нет, или если я комментирую основной поток, то нет ошибки,или если я не обновляю через пакет вместо этого, если я использую массовое обновление, то также нет ошибки.Если я прокомментирую пул авто-релиза, также появляется ошибка.Поможет ли мне какое-нибудь тело в этом, пожалуйста.

Заранее спасибо,

Приветствия, Шраван

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;
}

1 Ответ

1 голос
/ 24 августа 2011

Наиболее вероятной причиной описываемого вами сбоя является использование managedObjectContext в разных потоках.managedObjectContext не является потокобезопасным.Вы должны создать новый MOC для каждого потока.Я полагаю, managedObjectContext является иваром;вы никогда не должны обращаться к своим иварам напрямую, как это (за исключением init и dealloc).Всегда используйте аксессор для управления памятью.

Причина, по которой NSLog приводит к сбою, заключается в том, что NSLog резко меняет время этой функции, и у вас возникает состояние гонки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...