核心数据 - 以一对多关系访问实例与获取请求?
Posted
技术标签:
【中文标题】核心数据 - 以一对多关系访问实例与获取请求?【英文标题】:Core Data - accessing instances in a to many relationship vs fetch request? 【发布时间】:2013-03-29 13:41:55 【问题描述】:我的应用中有一个带有“笔记本”实体的核心数据模型。 有两种方法可以访问一个或多个“笔记本”实例:
通过执行带有谓词的 NSFetchRequest,请求具有特定“标题”或“索引”属性的实例。 通过在我的 Core Data 模型中添加一个 'AppData' 实体,放弃 'Notebook' 中的 'index' 属性,而是从 'AppData' 到 'Notebook' 建立一对多的有序关系。然后我会在第一个应用程序启动时创建一个“AppData”实例(并且在之后的每次启动时,我都会获取该唯一一个“AppData”实例的请求)并通过其对多关系访问所有“笔记本”实例。要按标题访问笔记本,我会使用 indexOfObjectPassingTest 或快速 obj-c 枚举,要按索引访问,我会使用 objectAtIndex。查询“AppData”实例以获取“笔记本”实例及其属性比每次都向托管对象上下文设置获取请求要容易得多。
但是,哪种方法更快?一种方法会使用更多内存还是在内存中停留更多时间?我读到多对关系中的对象是延迟加载的,但是什么时候加载该集合中的对象?什么时候卸载?
【问题讨论】:
【参考方案1】:AppData
实体似乎是多余的。您必须先获取它,那么为什么不获取所有 Notebook
实例呢?过滤(按标题、其他 ID 属性)在两种情况下都是相同的。
获取请求不一定是痛苦的:
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"Notebook"];
NSArray *fetchedObjects = [moc executeFetchRequest:fetch error:nil];
此外,根据数据量,您可以在内存中过滤这些数据,或在提取请求中包含谓词。
当然,无论场景如何,都要放弃“索引属性”的想法。 Core Data 是一个对象图,而不是数据库。这样做的唯一理由可能是您需要与某些使用唯一标识符的外部框架或数据存储同步。
为方便起见,您可以在托管对象的类别中创建一个方法。
+(NSArray*) appNotebooks
NSArray * fetchedResults = // fetch the appropriate entities
return fetchedResults;
然后你会这样使用它:
Notebook.appNotebooks;
【讨论】:
如果我一次获取所有笔记本,我将加载整个文件系统,这是我试图避免的。我想知道每次我需要一些笔记本实例时使用带有谓词的获取请求是否更好,或者我是否可以改为使用“AppData”对多关系并从该 NSOrderedSet 加载特定实例。访问 NSOrderedSet 中的实例相当于使用谓词获取,还是更像是一次在内存中加载所有笔记本,然后在内存中过滤以找到我需要的实例? 基本上我只是认为查询 NSOrderedSet 的代码比使用带有谓词的 fetch 请求更漂亮,并且想知道它们在执行和加载到内存中的方式是否相同。 你的问题不合逻辑。如果您有未使用的非“AppData”笔记本,只需删除它们即可。访问“AppData”笔记本与访问所有笔记本有何不同? -- 是的,访问关系就像一个带有谓词的获取请求。此外,您可以通过调整建模对象类并添加 fetch 方法来使 fetch 变得非常“漂亮”。 "访问“AppData”笔记本与访问所有笔记本有何不同?"正是我想知道的:如果我的所有笔记本都在一个 AppData 实例对多的关系中,我是否一次将它们全部加载到内存中,就像通过没有谓词的 NSFetchRequest 获取所有笔记本一样?还是 NSOrderedSet 仅在请求时才加载实例(当我调用 objectAtIndex 时)? 好吧,在这两种情况下,你都会得到一个完整的数组/指针集,但是 Core Data 使用“故障”在稍后需要时在后台获取一些属性或关系。所以,是的,它是相同的,没有性能差异。如果您需要内存优化,请使用 NSFetchedResultsController。以上是关于核心数据 - 以一对多关系访问实例与获取请求?的主要内容,如果未能解决你的问题,请参考以下文章