2011-08-24 85 views
0

我在后台线程上使用批量更新更新为核心数据时遇到问题。在下面的代码中,我使用主线程来通知用户进程视图和调用appdelegate中的方法的字符串。但是,如果我在NSEntity行中出现错误访问错误,那么在随机数据库中有数千个对象需要更新。如果我取消注释下面指出的NSLOG没有错误,或者如果我评论主线程没有错误,或者如果我不通过批量更新,而是使用批量更新,那么也没有错误。如果我评论autorelease池也出现错误。请一些身体帮助我这个请。使用线程批量更新到核心数据时出错

由于提前,

干杯, 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; 
} 

回答

1

那种你是跨线程使用managedObjectContext描述崩溃的最可能的原因。 managedObjectContext不是线程安全的。您必须为每个线程创建一个新的MOC。我认为managedObjectContext是一个伊娃;你不应该直接像这样访问你的ivars(init和dealloc除外)。始终使用访问器为您处理内存管理。

原因NSLog使它崩溃是因为NSLog戏剧性地改变了这个功能的时间,并且你有一个竞争条件。

+0

感谢罗布,我也怀疑如此关于这个问题是因为时间变化发生的事情,当然是真的,我们需要为每个线程创建MOC新的核心数据不是线程安全的,我尝试在这个早上,它工作得很好。再次感谢您的回答。 – Star