Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 使用线程批量更新核心数据时出错_Iphone_Ios_Ipad_Core Data - Fatal编程技术网

Iphone 使用线程批量更新核心数据时出错

Iphone 使用线程批量更新核心数据时出错,iphone,ios,ipad,core-data,Iphone,Ios,Ipad,Core Data,我在后台线程上使用批更新来更新核心数据时遇到了一个问题。在下面的代码中,我使用主线程通知用户一个进度视图和一个字符串,该字符串调用appdelegate中的方法。但是,如果我在随机数目的数据中的N实体行中遇到错误的访问错误,我有数千个对象要更新。如果我取消注释下面指出的NSLOG,则没有错误,或者如果我注释主线程没有错误,或者如果我不通过批更新,而使用批量更新,则也没有错误。如果我对自动释放池进行注释,也会出现错误。请找个人帮我一下好吗 提前感谢, 干杯, 什拉文 NSAutoreleasePo

我在后台线程上使用批更新来更新核心数据时遇到了一个问题。在下面的代码中,我使用主线程通知用户一个进度视图和一个字符串,该字符串调用appdelegate中的方法。但是,如果我在随机数目的数据中的N实体行中遇到错误的访问错误,我有数千个对象要更新。如果我取消注释下面指出的NSLOG,则没有错误,或者如果我注释主线程没有错误,或者如果我不通过批更新,而使用批量更新,则也没有错误。如果我对自动释放池进行注释,也会出现错误。请找个人帮我一下好吗

提前感谢,

干杯, 什拉文

NSAutoreleasePool*tempPool=[[NSAutoreleasePool alloc]init];
整数迭代器=1;
对于(int i=0;i
您描述的这种崩溃最可能的原因是跨线程使用
managedObjectContext
<代码>managedObjectContext不是线程安全的。您必须为每个线程创建一个新的MOC。我假设
managedObjectContext
是一个ivar;您不应该像这样直接访问IVAR(init和dealloc除外)。始终使用存取器为您处理内存管理


NSLog
使其崩溃的原因是
NSLog
极大地改变了此函数的计时,并且您有一个竞争条件。

谢谢Rob,我也对这个问题产生了怀疑,因为发生了时间变化,是的,当然你是真的,我们需要为核心数据不是线程安全的每个线程创建新的MOC,我今天早上尝试过,它工作得很好。再次感谢你的回答。
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;
}