0

このスクリーンショットに示すように、次のカレンダー期間で構成され、モデル化されていますNSArrayNSManagedObjects

CoreDataModel

次のサンプル コンテンツを使用します。

endMonth = 9;
endYear = 2012;
length = 3;
...

私がやろうとしていること:

1 年前の同等の期間が存在する暦期間のみを返す述語を作成しようとしています。例:配列2012, 9, 3に期間がある場合にのみ、期間 (年、月、長さ) を結果として返します。2011, 9, 3述語は、すべてのカレンダー期間を配列内の各カレンダー期間と比較する必要があります。

これは私が試した述語です:

predicate = [NSPredicate predicateWithFormat:
       @"SUBQUERY(SELF, $x, $x.endYear == endYear - 1 "
        "AND $x.endMonth == endMonth AND $x.length = length).@count > 0"];

問題:

ただし、この述語を使用してアプリを実行すると、ランタイム クラッシュが発生し、次のエラー メッセージが表示されます: NSInternalInconsistencyException', reason: 'Can't perform collection evaluate with non-collection object.'。

述語の何が問題なのですか? また、述語を正しく指定するにはどうすればよいですか?

ありがとうございました!

4

1 に答える 1

2

まず、表示されているエラーに対処します。これはあなたの述語です:

[NSPredicate predicateWithFormat:@"SUBQUERY(SELF, $x, $x.endYear == endYear - 1 "
    "AND $x.endMonth == endMonth AND $x.length = length).@count > 0"]

式の最初の引数は、が反復SUBQUERYするコレクションです。したがって、 anまたは an のいずれかに評価されることをSUBQUERY期待しています。ただし、サブクエリ述語でのキーパス、、、およびの使用は、に評価されることを期待していることを示しているようです。したがって、コレクション (および、、およびはコレクションの無効なキーパス) であるか(したがって、 のコレクションとして使用できません。エラーに基づいて、後者のようです。SELFNSArrayNSSetendYearendMonthlengthSELFCalendarPeriodSELFendYearendMonthlengthSELFCalendarPeriodSUBQUERY

問題を( を使用せずに)書き出すとしNSPredicateたら、おそらく次のような結果になるでしょう。

NSArray *calendarPeriods = ...;
for (CalendarPeriod *period in calendarPeriods) {
  for (CalendarPeriod *otherPeriod in calendarPeriods) {
    if ([otherPeriod endYear] == [period endYear] - 1 && [otherPeriod endMonth] == [period endMonth] && [otherPeriod length] == [period length]) {
      return YES;
    }
  }
}
return NO;

では、これを再現するにはどうすれば...

あなたの最初の試みはかなり良いようです。行う必要がある唯一の変更はSELF、 の最初のパラメーターとしてではなく、SUBQUERYを使用し、そこのコレクションで%@代用することだと思います。calendarPeriodsまたは、 this を an の述語として実行している場合は、式を使用してすべてのオブジェクトをフェッチNSFetchRequestすることもできます。FETCH()CalendarPeriod

ところで、このルートに行くと、パフォーマンスがかなり悪くなります。これは保証された O(N 2 ) であり、はるかにうまくいく可能性があります。たとえば、every をメモリにフェッチしてから、 、、およびの組み合わせでキー付けさCalendarPeriodれた に挿入した場合、O(N) 時間に短縮できます。NSDictionaryendYearendMonthlength

于 2012-11-04T21:28:48.530 に答える