コアデータの問題については少し詳しくないので、ガイダンスをいただければ幸いです。対多関係に基づく依存プロパティを使用する NSSortDescriptor を使用して NSFetchRequest を作成したいと考えています。
Apple の側では、ドキュメントには、これを行うことはできないと書かれています。私を混乱させているのは、NSSortDescriptor の一部として使用した場合にのみ機能しないということです。リクエストの NSPredicate と私の ManagedObject サブクラスで動作します。
要するに、多くの Checkin オブジェクトを持つことができる Venue オブジェクトで構成される単純なオブジェクト モデルがあります。各 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' が原因でアプリを終了しています。checkins.@sum.hereNow の処理に失敗しました'
しかし、完全に機能する MapView コントローラー用の同様の fetchRequest があります (名前フィールドを使用するように NSSortDecriptor を設定しただけです)。TableView fetchRequest に対して同じことを行うと、それも機能し、新しいチェックイン オブジェクトが追加されたときに会場の数が正しく更新されるように見えます。そのため、述語でその keyPath を使用しても問題はないようです。sortDecriptor だけです。
ただし、 Appleのドキュメントには次のように書かれています;-
対多関係に依存関係を設定することはできません。たとえば、OrderItem オブジェクトのコレクションに対して対多の関係 (orderItems) を持つ Order オブジェクトがあり、OrderItem オブジェクトに price 属性があるとします。Order オブジェクトには、関係にあるすべての OrderItem オブジェクトの価格に依存する totalPrice 属性が必要になる場合があります。keyPathsForValuesAffectingValueForKey: を実装し、totalPrice のキーパスとして orderItems.price を返すことによってこれを行うことはできません。orderItems コレクション内の各 OrderItem オブジェクトの price 属性を観察し、totalPrice を自分で更新して値の変更に対応する必要があります。
これは十分に明確に思えますが、述語で同じことを実行できる理由がわかりません。これは私の最初の Core データ アプリなので、少し慣れていません。KVO、KVC などに関するいくつかの質問を読んだことがありますが、実際には適切に把握できていません。ご覧のとおり、私が実際にやろうとしているのは、派生した "hereNow" カウントの合計に基づいて Venues のコレクションを並べ替えることだけです。おそらく、私はこれについて完全に間違った方法で進んでいますか?もしそうなら、正しい方向への友好的な舵取りに感謝します!