Core Data 后台排序
Posted
技术标签:
【中文标题】Core Data 后台排序【英文标题】:Core Data background sorting 【发布时间】:2011-11-08 15:05:01 【问题描述】:我有一个Department
实体,它与Employee
实体具有一对多关系。在运行时,对于每个Department
对象,我想维护一个Employee
对象的排序数组(根据某些属性排序),它将用作各种视图对象中的模型。
从我读到的有两种方式来表示排序数组:
Rep1:在Department
中定义一个获取的属性(排序由Core Data完成);
Rep2:在Department中维护一个实例变量sortedEmployees
(NSArray
of Employee
objects)(排序由我的代码完成)。
现在我真正的问题是,当应用程序启动时,我有大量的 Departments
和 Employees
要从持久存储中获取。我想在后台执行排序,以免阻塞 UI。
我尝试了几种方法,但都无济于事:
Method1(使用Rep1):在后台线程中(使用NSOperationQueue
),获取所有Departments
,然后执行每个获取的属性。然后回到主线程,在主线程的托管对象上下文(MOC)中找到对应的Department
对象(通过NSManagedObjectID)并使用fetched属性。
Method1的问题:即使后台Department的fetch完成后,主线程Department对象中的fetched属性也没有填充,这意味着它在主线程Department中重新获取!这违背了后台获取的全部目的。我假设一个获取的属性一旦被获取,就存在于所有 MOC 中,我错了吗?
Method2(使用Rep2):在后台线程中(使用NSOperationQueue
),获取所有Departments
,然后计算每个sortedEmployees
数组。然后回到主线程,在主线程的MOC(通过NSManagedObjectID)中找到对应的Department对象,将上述数组设置为这个对象 .
方法 2 的问题:sortedEmployees
数组中的对象是属于后台线程的 MOC 的 Employee
对象。当主线程稍后尝试访问它们时,会发生类似"NSManagedObject with ID ... has been invalidated."
的崩溃,这是因为每个线程都必须有自己的 MOC(及其关联的托管对象)。
如果托管对象不能跨线程边界存在,那么如何在后台对托管对象进行排序呢?我错过了什么吗?
【问题讨论】:
【参考方案1】:庇护,
你没有错过任何东西。您只需要将排序后的数组转换为新的 MOC。这是一个片段:
NSMutableArray *ma = [NSMutableArray arrayWithCapacity: array.count];
for (mo in array)
[ma addObject: [moc objectWithID: mo.objectID]];
return ma;
这将迁移您的阵列。据我了解,这是一个有效的过程。此外,您可以依赖行缓存来对属性进行高性能访问。
安德鲁
【讨论】:
谢谢。您能否根据行缓存详细说明您的意思?什么行缓存? 另外,我应该在哪个线程中执行上述数组迁移?在主线程的情况下,当您访问 mo.objectID 时,“mo”是否会失效并因此出错?在后台线程的情况下,访问[moc objectWithID:...]会不会有问题,因为moc属于主线程? Pius,行缓存由持久存储协调器维护。这是一种自动性能优化。你不需要维护它——Core Data 会。当我在目标线程上时,我通常会转换 ID。安德鲁 P.S.如果您喜欢这个答案,请记得选择它作为“正确”答案。以上是关于Core Data 后台排序的主要内容,如果未能解决你的问题,请参考以下文章
使用 Core Data 进行排序的 fetchRequest 有啥限制?