使用to对依赖属性排序NSFetchRequest
希望得到一些指导,因为我在核心数据问题上有点超出我的深度。 我想用NSSortDescriptor创建一个NSFetchRequest,它使用基于一对多关系的依赖属性。
对于苹果公司来说,文档说你不能这样做。 令我困惑的是,只有当我将它用作NSSortDescriptor的一部分时,它才会起作用。 在请求的NSPredicate和我的ManagedObject子类中它工作。
总之,我有一个简单的对象模型,它包含一个Venue对象,并且可以有许多Checkin对象。 每个Checkin对象都有一个名为hereNow的属性。
@interface Venue : NSManagedObject <MKAnnotation> {}
@property (nonatomic, readonly, retain) NSNumber * hereNow;
@end
@interface Venue (CoreDataGeneratedAccessors)
- (void)addCheckinsObject:(NSManagedObject *)value;
- (void)removeCheckinsObject:(NSManagedObject *)value;
- (void)addCheckins:(NSSet *)value;
- (void)removeCheckins:(NSSet *)value;
@end
@implementation Venue
- (NSNumber *)hereNow {
return [self valueForKeyPath:@"checkins.@sum.hereNow"];
}
@interface Checkin : Update {}
@property (nonatomic, retain) Venue * venue;
@property (nonatomic, retain) NSNumber * hereNow;
@end
@implementation Checkin
@dynamic venue;
@dynamic hereNow;
@end
到现在为止还挺好。 这是来自TableView控制器的fetchRequest
// Create and configure a fetch request with the Venue entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Venue" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Create a predicate to filter the results
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"checkins.@sum.hereNow > 0"];
[fetchRequest setPredicate:predicate];
// Create the sort descriptors array.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"checkins.@sum.hereNow" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Create and initialize the fetch results controller.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:nil
cacheName:@"Venues"];
使用该代码,我得到以下错误
由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'包含KVC聚合的Keypath不应该有一个; 无法处理checkins。@ sum.hereNow'
但我有一个类似的fetchRequest的MapView控制器完美的工作(我只是设置NSSortDecriptor使用名称字段)。 如果我为TableView fetchRequest执行相同的操作,那么也会起作用,并且在添加新的签入对象时,场地计数似乎会正确更新。 所以在谓词中使用keyPath似乎没有问题,只是sortDecriptor。
然而,苹果的文档说这个;
您不能在多对多关系上设置依赖关系。 例如,假设您有一个Order对象与一个OrderItem对象集合具有一对多关系(orderItems),并且OrderItem对象具有一个price属性。 您可能希望Order对象具有一个totalPrice属性,该属性取决于关系中所有OrderItem对象的价格。 您无法通过实现keyPathsForValuesAffectingValueForKey来完成此操作,并且返回orderItems.price作为totalPrice的关键路径。 您必须遵守orderItems集合中每个OrderItem对象的price属性,并通过自己更新totalPrice来响应其值的更改。
这似乎很清楚,但我不明白为什么我可以在谓词中做同样的事情? 这是我的第一个核心数据应用程序,所以我对它有点新。 我已经阅读了几个关于KVO,KVC等的问题,我没有真正掌握这些问题。 正如你所看到的,我真正想要做的就是根据他们的派生总数“hereNow”计数排序场馆集合。 也许我正在以完全错误的方式解决这个问题? 如果是这样,将感激一个友好的引导在正确的方向!
我能想到的几件事情:
在SortDescriptor上,您不能使用@sum来计算排序值。 你必须在其他地方计算。 我相信这就是为什么它说“含有KVC聚合物”。 因为您正在使用“键”值创建排序描述符,所以它必须是该对象的实际属性。
当您的Venue对象中有派生属性时,您不应该使其依赖于遍历关系的其他对象。 您的“hereNow”属性无法遍历Checkin对象以获取Venue对象返回的值。 我相信派生属性只允许访问同一对象中的其他属性。
尝试一种可能的方法是更改排序描述符键以尝试initWithKey:@“hereNow”。
它与你的MapView控制器一起工作的原因是(我从你的问题推断出来)是name字段位于同一个对象上,并且不会通过关系来获取该值。
我可以建议的最好的事情是在Venue对象上添加一个实际属性,每次更改Checkins时都会更新它。 我知道这不完全是你想要的,但它会起作用。
顺便说一下,keyPathsForValuesAffectingValueForKey可以在Mac上使用,但不能在iOS上使用。 它会告诉父对象什么时候需要更新。 请参阅注册从属关键字部分:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVODependentKeys.html#//apple_ref/doc/uid/20002179-BAJEAIEE
如果您是CoreData的新手,我会推荐Marcus Zarra出色的书籍:https://pragprog.com/titles/mzcd/core-data
希望这可以帮助。
链接地址: http://www.djcxy.com/p/36141.html上一篇: Sorting an NSFetchRequest by a dependent property using a to