核心数据多对多关系更新导致故障

时间:2013-10-01 10:01:45

标签: iphone ios objective-c core-data key-value-observing

我正在开发一个具有以下多对多模型的项目:

书:可以有多个标签(book.tags) 标签:可以包含很多书籍(tag.books)

我发现当一本书已经在数据库中而我只是想通过[bookMO addTagsObject:tag]为该书添加标签时,我会在book.tags中出错。使用该工具,我发现核心数据正在尝试“[NSObject(NSKeyValueObserver(Notification) willChangeValueForKey:withSetMutation:usingObjects]”。

我还检查了实际的sql被执行,我发现: 注释:从数据库中完成objectID 0x20140b00的多对多关系错误“标记”。 然后是一个sql查询,它返回包含这本书的所有标签。我发现内部核心数据使用Book和Tag的连接表。该连接表的主键只是book_id and tag_id的组合。该联合表未编入索引。并且为了获得包含书籍的所有标签,似乎(我不确定这里)遍历该联合表中的所有行,因此这个操作非常昂贵。

我认为现在我的应用程序正在发生的事情是,每次我想在书中添加标签时,我都必须在联合表中进行线性扫描。总体复杂度为O(N^2),因为每个操作都会在连接表中进行线性扫描。我现在有10k书,表现不太好......

有什么办法可以避免kvo触发的tags错误?或者有什么方法可以实现我自己的连接表,可以通过索引返回O(1)中的结果?

-Erben

1 个答案:

答案 0 :(得分:0)

抱歉延迟更新。

核心数据对于多对多关系并不好,因为它不会创建我想要的索引。

我最终创建了一个RleationManagedObject。它有一个指向BookManagedObject的属性“book”和一个指向TagManagedObject的属性“tag”。两个属性都被编入索引(非常重要,默认核心数据不会索引这两个属性)。

每次我需要在“book_1”上添加“tag_1”时,我会使用“book_1”和“tag_1”搜索所有RelationManagedObject。如果没有找到,我创建这个relationManagedObject。我也可以用<“book_1”,“tag2”>或者<“book_2”,“tag_1”>等创建relationManagedObject。基本上我自己管理这段关系。

所以问题是核心数据多对多关系没有正确索引。

此外,xcode可以打印出它执行的sql。第一次打开应用程序时,它将创建您在核心数据中定义的那些表。因此,您可以看到CoreData Framework如何在没有正确索引的情况下创建默认的“关系”表。这就是我如何找到问题的。