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

标签 iphone ios ipad core-data

我在后台线程上使用批量更新更新核心数据时遇到问题。在下面的代码中,我使用主线程通过进度 View 和调用 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;
}

最佳答案

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

NSLog 使其崩溃的原因是 NSLog 极大地改变了该函数的时间,并且存在竞争条件。

关于iphone - 使用线程批量更新核心数据时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7174994/

相关文章:

ios - UIView 卡在 UITableview header 后面

ios - 使用缓冲区上传 iOS 7

iphone - iPhone开发证书可以重复使用吗?

ios - UIWebView 中的全屏视频会干扰 UIViewController 的输入附件 View

ios - 以编程方式选择 TableView 上的单元格不会执行关联的 segue

iphone - 保存登录凭据 Xcode

Iphone:将音频创建为文件时找不到音频 Assets 轨道,在应用程序中运行

ios - 如何在iOS应用程序中随着背景音乐一起播放声音?

ios - 如何即时操作纹理内容?

ios - 如何在 UIPopoverController 中设置 UITableView 的背景颜色?