【发布时间】:2013-11-20 21:02:25
【问题描述】:
对于 TableViewController,我正在创建一个 NSFetchedResultsController。
模型看起来像:EntityA > EntityB。在下面的代码中,关系称为 entityRelationship。 EntityB 有一个 NSNumber 属性,称为属性。
我需要对结果进行过滤和排序。我是这样做的:
predicate = [NSPredicate predicateWithFormat:@"entityRelationship.@count > 0"];
[fetchRequest setPredicate:predicate];
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"entityRelationship.@avg.attribute"
ascending:NO];
基本上,我需要显示所有具有非空 entityRelationship 的实体,并按 entityB 属性的平均值对其进行排序。
显示的代码抛出异常:* 由于未捕获的异常“NSRangeException”而终止应用程序,原因:“-[__NSCFString characterAtIndex:]: Range or index out of bounds”
sortDescriptor 不是仅适用于谓词过滤的结果吗?我怎样才能在一个请求中实现这一目标? (由于这个请求链接到一个 NSFetchedResultsController,我不想先获取然后排序)。
谢谢!
编辑
根据邓肯的回答,我找到了解决方案。我仍然认为发布我的答案是相关的,使用与我的问题相同的示例。
在基于 EntityB 的类别中,我覆盖了属性的设置器。 (我需要知道 EntityA 中所有属性的平均值才能对它们进行排序)。代码如下:
- (void)setAttribute:(NSNumber *)attribute
{
[self willChangeValueForKey:@"attribute"];
[self setPrimitiveValue:attribute forKey:@"attribute"];
[self didChangeValueForKey:@"attribute"];
EntityA *entityA = self.entityA;
float mean = 0;
int nbItems = 0;
for (EntityB *b in entityA.entityB)
{
mean += [b.attribute floatValue];
nbItems++;
}
[entityA setAvgAttribute:[NSNumber numberWithFloat:(mean/nbItems)]];
}
这样,我每次在EntityB中设置属性时,都会重新计算平均值,这正是我所需要的。谢谢!
【问题讨论】:
-
异常是在第一行还是最后一行抛出?
-
执行fetch时抛出,在fetch行:
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; -
当然,呃(我是说)。尝试根据指示不允许使用 KVC 聚合的子项数量进行排序时,出现以下异常。不足为奇,因为您不能只指定一个 keyPath 一个键。由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“包含 KVC 聚合的密钥路径不应存在;未能处理孩子。@count'
-
一种简单的方法是创建一个持久性属性并使用子属性的平均值保持更新。
-
听起来很有希望。我猜想覆盖影响该实体类别中此平均值的属性的设置器(示例中为 EntityB)可以解决问题吗?
标签: ios core-data nspredicate nsfetchedresultscontroller nssortdescriptor