【问题标题】:Core data - Collection NSCFSet was mutated while being enumerated核心数据 - 集合 NSCFSet 在枚举时发生了变异
【发布时间】:2015-05-23 23:15:37
【问题描述】:

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

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

出现错误 Collection __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;
    }

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

【问题讨论】:

    标签: ios objective-c multithreading core-data


    【解决方案1】:

    首先,请注意,当您读取数据时多个线程访问您的数据时,可能会出现竞争条件。你可能没有读到你想读的东西。

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

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

    【讨论】:

    • 此外,您使用的方法可能无法按预期工作。两个线程可能同时写入数据,并且在调用 [context save:&error] 之前,此数据保持未提交状态,因此其他线程在尝试执行 NSFetchRequest 时将无法获取此数据。
    猜你喜欢
    • 1970-01-01
    • 2011-03-17
    • 2016-11-20
    • 2017-06-28
    • 2014-02-15
    • 2017-11-22
    • 2015-11-13
    • 2013-01-29
    • 2011-03-27
    相关资源
    最近更新 更多