在 coredata 中过滤 Vs NSPredicate

Posted

技术标签:

【中文标题】在 coredata 中过滤 Vs NSPredicate【英文标题】:Filter Vs NSPredicate in coredata 【发布时间】:2020-07-20 11:18:36 【问题描述】:

我知道您不能将 coredata 视为关系数据库,因为它是一个对象图(如果我错了,请纠正我)。因此,当您使用谓词调用获取请求时,我对内存中发生的情况有点迷茫。

    是先将整个实体加载到 ManageObjectContext,然后在谓词的帮助下进行过滤,还是直接作为关系数据库进行过滤(直接从表中选择值,就像选择查询在一个关系数据库)??

    如果它将整个实体加载到内存中,为什么不使用“过滤器”而不是“NSPredicate”

如果有适当的 Apple 参考答案将不胜感激。

【问题讨论】:

如果您启用 Core Data 日志记录(参见例如***.com/a/12306537/1187415),那么您会看到 NSPredicate 过滤是在 SQLite 级别完成的,即在内存中创建托管对象之前。 【参考方案1】:

来自核心数据编程指南中的Persistent Store Types and Behaviors(强调添加):

抓取方式因商店类型而异。在 XML、二进制和内存存储中,谓词和排序描述符的评估是在 Objective-C 中执行的,可以访问所有 Cocoa 功能,包括 NSString 上的比较方法。

另一方面,SQLite 存储将谓词和排序描述符编译为 SQL,并在数据库本身中评估结果。这样做主要是为了提高性能, ...

您可以通过启用 Core Data 调试来验证这一点。设置

-com.apple.CoreData.SQLDebug 3
-com.apple.CoreData.Logging.stderr 1  

作为环境变量,您将在执行 SQLite 语句时看到它们。

【讨论】:

【参考方案2】:

答案是“视情况而定”。获取请求被分派到您正在使用的核心数据存储。由该商店决定如何处理获取请求。

最常与 Core Data 一起使用的 SQLite 存储将谓词转换为 SQL 查询。其他存储类型可能无法做到这一点,可能需要在内存中执行过滤。

【讨论】:

所以这意味着如果你使用 NSPredicate,它实际上可以直接从 SQLLite DB 中选择一个值,而不是先加载到上下文中并进行过滤。你是这么说的吗?

以上是关于在 coredata 中过滤 Vs NSPredicate的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 coreData 过滤数据

tableView中过滤coredata模型

从 coredata 中过滤值并分配给 tableview

如何从coredata中的实体获取过滤数据

SwiftUI:如何将 CoreData 与动态过滤器相加?

浅谈SwiftUI 3.0新加入的CoreData动态FetchRequest过滤与排序特性