核心数据 - 集合NSCFSet在枚举时发生了变异

时间:2015-03-20 14:01:49

标签: ios objective-c multithreading core-data

插入数据时我遇到了问题。我正在检查条件,如果数据不存在然后插入但应用程序崩溃

BOOL isExist = [context countForFetchRequest:request error:&error];

错误集合__NSCFSet在枚举时发生了变异。

但是后台线程上同时运行了更多操作。这将使用核心数据进行更多操作。

appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
        NSManagedObjectContext *context = appDelegate.managedObjectContext;

    NSError *error;
    for (StreamData *stream in streamData) {
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:DB_TABLE_STREAM];
        [request setPredicate:[NSPredicate predicateWithFormat:@"stream_id = %@", stream.messageId]];
        [request setFetchLimit:1];
        BOOL isExist = [context countForFetchRequest:request error:&error];

        if (!isExist) {
            CF_Stream *object = [NSEntityDescription insertNewObjectForEntityForName:DB_TABLE_STREAM inManagedObjectContext:context];
            [object setStream_id:[NSNumber numberWithLongLong:[stream.messageId longLongValue]]];
            [object setType:stream.streamType];
            [object setTime_stamp:[[DateTimeManager sharedInstances] getStreamDate:stream.streamTime]];
        }
    }
    if (![context save:&error]) {
        NSLog(@"Failed to sve - error: %@", error);
        return NO;
    } else {
        return YES;
    }

非常感谢任何帮助。 谢谢!

1 个答案:

答案 0 :(得分:3)

首先,请注意当多个线程在您阅读时访问您的数据时可能存在竞争条件。您可能无法阅读您想要阅读的内容。

解决问题的一种快速方法应该是使用streamData迭代for each,而是使用带索引的标准for迭代器。也就是说,您仍需要注意,在迭代它时可能会更改streamData,因此您需要添加检查。

可能有更好的方法。也许你可以一起避免这种迭代。