【问题标题】:Core Data/NSOperation: crash while enumerating through and deleting objectsCore Data/NSOperation:枚举和删除对象时崩溃
【发布时间】:2011-09-02 15:45:52
【问题描述】:

我有一个基于核心数据的应用程序,它具有一个对象(列表)与多个对象(列表项)的关系。我正在处理设备之间的数据同步,作为其中的一部分,我从后台线程中的 XML 文件导入列表(通过 NSOperation 子类)。

当我更新现有列表时,我会删除其所有旧列表项(从特定于该线程的 NSManagedObjectContext 中)并用 XML 文件中的新项替换它们...删除是通过枚举来处理的该列表的项目:

for (ListItemCD *item in listToUpdate.listItems) {
    [self.importContext deleteObject:item];
}

但是,偶尔,我在该枚举期间遇到崩溃:

* 由于未捕获的异常“NSGenericException”而终止应用程序,原因:“* 集合 <0x4fcfcb0>

&amp;&gt;&amp;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&amp;

    标签: ios core-data nsoperation fast-enumeration


    【解决方案1】:

    错误消息中有一点线索,您可以在其中看到列出的类NSFaultingMutableSet。实际上,您枚举的集合实际上只是可能会按需加载数据的一对多关系的代理。由于集合中的项目在枚举过程中被标记为已删除,因此在您枚举集合时可能会“更改”某些集合,并且您会看到该错误。

    处理此问题的常用方法是创建集合的副本并枚举该副本。天真的方法就是:

    NSSet *iterItems = [[list.items copy] autorelease];
    for (ListItemCD *item in iterItems) { ... }
    

    但我在处理 Core Data 时发现 -copy 实际上并没有返回副本,而通常只是另一个错误代理。所以我改为选择以这种方式复制集合:

    NSSet *iterItems = [NSSet setWithSet:list.items];
    for (ListItemCD *item in iterItems) { ... }
    

    【讨论】:

    • 这似乎已修复它...经过 20 分钟的测试,我没有再次看到错误。我以为我看到过代码示例,人们使用快速枚举来删除 Core Data 关系中的对象,就像我正在做的那样——但显然这样做并不安全。正如你所展示的,最好先复制一套。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    相关资源
    最近更新 更多