2011-08-24 3 views
0

バックグラウンドスレッドでバッチ更新を使用してコアデータを更新する際に問題が発生しました。以下のコードでは、メインスレッドを使用して進行状況ビューとappdelegateでメソッドを呼び出す文字列をユーザーに通知しています。しかし、NSEntity行のデータの乱数が乱数で更新されていない場合、update.ifには何千ものオブジェクトがあります。NSLOGのコメントを外していますが、エラーはありません。または私は一括更新を使用していない場合、代わりにバッチを介して更新しない場合、エラーもありません。私はautoreleaseプールをコメントしても、エラーが表示されます。この体で私の体を助けてくれますか?事前にスレッドでコアデータに一括更新する際のエラー

おかげで、

乾杯、

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

Shravanあなたがスレッド間であなたのmanagedObjectContextを使用している記述しているクラッシュの種類の原因として最も可能性が高いです。 managedObjectContextはスレッドセーフではありません。スレッドごとに新しいMOCを作成する必要があります。私はmanagedObjectContextと思います。このように直接あなたのivarsにアクセスすべきではありません(initとdeallocを除く)。常にあなたのためのメモリ管理を処理するアクセッサを使用してください。

NSLogがクラッシュする理由は、NSLogがこの機能のタイミングを大幅に変更し、競合状態になっているためです。

+0

ありがとうございました。私は疑問が残っていました。タイミングの変更がbecozでした。もちろん、コアデータがスレッドセーフではないスレッドごとに新しいMOCを作成する必要があります。朝はうまくいった。ウルのお返事ありがとうございました。 – Star