【发布时间】:2013-07-21 14:27:07
【问题描述】:
场景
我有两个实体:Item 和 ListDetail(其中包含每个项目的不同列表的价格)。这是绝对需要的,我无法为 Item 实体提供价格属性,因为每个项目都可以为不同的动态列表(零售、b2b ecc)提供更多价格。
关系是:
Item (lists) <------->> (item) ListDetail
我的应用程序中的当前活动列表会发生动态变化,因此假设我有一个包含当前活动列表的整数变量:_ACTIVE_LIST_CODE_。当我需要商品对象的价格时,我会在 Item 类上使用辅助方法:
-(NSNumber*) getPrice {
NSSet *lists=[self.lists filteredSetUsingPredicate: [NSPredicate predicateWithFormat:@"listId == %d",_ACTIVE_LIST_CODE_]];
ListDetail *activeList=[[lists allObjects] objectAtIndex:0];
return activeList.price;
}
问题
我使用带有 NSFetchedResultController 的 UITableView 来选择和显示不同部分的一些项目。没什么特别的。我想使用活动列表的项目价格订购 fetchedObjects。如果价格是 Item 的一个属性,我会像这样在 fetch 请求中简单地添加一个排序描述符:
[NSSortDescriptor sortDescriptorWithKey:@"price" ascending:YES];
但正如之前所说,这是不可能的,价格是一个动态属性。
如果排序描述符可以使用瞬态属性,我将使用我的辅助方法设置一个动态计算的价格瞬态属性。无事可做。
不可能在描述符中使用像“lists.price”这样的键路径(或者我可能不知道该怎么做),因为它是一对多的关系,并且是用 NSSet 建模的。
我尝试了一些解决方法,但没有成功:
1) 观察 _ACTIVE_LIST_CODE_ 更改以在非瞬态属性中设置项目价格。
2) 在获取请求之后,在呈现表视图之前,使用瞬态“price”属性重新排序一个包含获取对象的全新数组,在升序整数索引“i”之后迭代排序数组并将此值分配给Item 实体的非瞬态属性“order”。在获取请求中使用“order”作为排序描述符。 (这里描述了这种方法:Re-ordering NSFetchedResultsController)
它们都可以工作,但它们会降低性能,因为我在提取结果中有数千个项目......有什么想法吗?
【问题讨论】:
-
1) 如何减慢速度?活动列表代码应该不会频繁或大量更改,对吧?
-
当用户选择不同的客户端时,列表代码可能会改变。这种情况发生的频率并不高,但即使一次,对 50k 项进行 for 循环、更改价格属性并保存上下文也会使应用程序冻结 8-9 秒。这是不可接受的!
-
您可以在后台线程上进行更新,并通过 NSFetchedResultsControllerDelegate 更新 UI。
-
当然可以,但这不是一个很大的优势:项目需要在客户选择后立即显示(这意味着活动列表更改),所以我需要更新价格属性并对项目进行排序按价格。
-
这不合逻辑。要么有设备更改--> 巨大更新--> 后台线程。或者有一个活动列表更改--> 小更新--> 立即从 bg 线程返回。
标签: core-data one-to-many nsfetchedresultscontroller nsfetchrequest nssortdescriptor