3

コアデータの問題については少し詳しくないので、ガイダンスをいただければ幸いです。対多関係に基づく依存プロパティを使用する 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 のコレクションを並べ替えることだけです。おそらく、私はこれについて完全に間違った方法で進んでいますか?もしそうなら、正しい方向への友好的な舵取りに感謝します!

4

1 に答える 1

3

私が考えることができるいくつかのこと:

  1. SortDescriptor では、@sum を使用してソート値を計算することはできません。他の場所でそれを計算する必要があります。「KVC凝集体を含む」と書いてあるのはそのためだと思います。「キー」値を使用してソート記述子を作成しているため、オブジェクトの実際のプロパティである必要があります。

  2. Venue オブジェクトに派生プロパティがある場合、関係を横断する他のオブジェクトに依存させないでください。「hereNow」プロパティは、Checkin オブジェクトをトラバースして、Venue オブジェクトで返される値を取得できません。派生プロパティは、同じオブジェクト内の他のプロパティへのアクセスのみが許可されていると思います。

試行できる 1 つの方法は、並べ替え記述子キーを initWithKey:@"hereNow" だけを試すように変更することです。

MapView コントローラーで動作する理由 (質問から推測しています) は、名前フィールドが同じオブジェクト上にあり、その値を取得するために関係をたどらないためです。

私が提案できる最善の方法は、チェックインを変更するたびに更新される Venue オブジェクトに実際のプロパティを追加することです。私はそれがあなたが望むものではないことを知っていますが、それはうまくいくでしょう.

ちなみに、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

お役に立てれば。

于 2011-06-16T13:42:52.403 に答える