0

これは私を困惑させています:

次のコードを使用して検索/フィルタリングするコアデータセットがあります。

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Lead" inManagedObjectContext:moc]];
NSString *predicateString = [NSString stringWithFormat:@"("
                       "(isLocalVersion == %@) AND (LeadStatusID =='Active')"
                       ") AND ("
                       "(LeadID contains[cd] '%@')"
                       "OR (AccountNumber contains[cd] '%@')"
                       "OR (ANY contactItems.FirstName contains[cd] '%@')"
                       "OR (ANY contactItems.LastName contains[cd] '%@')"
                       "OR (ANY addressItems.Address1 contains[cd] '%@')"
                       "OR (ANY addressItems.City contains[cd] '%@')"
                       ")", [NSNumber numberWithBool:YES], sTerm, sTerm, sTerm, sTerm, sTerm, sTerm];

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
[fetchRequest setPredicate:predicate];

NSError *error = nil;
NSArray *leads = nil;
@try {
    leads = [moc executeFetchRequest:fetchRequest error:&error];
}
@catch (NSException *exception) {
    LogSevere(@"Error Executing Fetch Request: %@", exception);
    leads = [NSArray array];
}
@finally {
    [fetchRequest release];
}

sTermは単なるNSString。です。

これは95%の確率で機能しますが、たまにNSInvalidArgumentException: Can't use in/contains operator with collection 10076173 (not a collection).

述語文字列の形式は次のとおりです。

((isLocalVersion == 1)AND(LeadStatusID =='Active'))AND((LeadID contains [cd]'i')OR(AccountNumber contains [cd]'i')OR(ANY contactItems.FirstName contains [cd] 'i')OR(ANY contactItems.LastName contains [cd]'i')OR(ANY addressItems.Address1 contains [cd]'i')OR(ANY addressItems.City contains [cd]'i'))

私のキャッチでは、クラッシュせずに0の結果を返すことができますが、これは最適ではありません。誰かがこれを見たことがありますか?

私の唯一の手がかりは、コアデータのレコードを変更(および保存)した後に発生するように見えることです(これも時々だけです)。

4

5 に答える 5

2

はい、fetchRequestの述語の一部としてコレクションに評価される式を使用することはできません。 これはドキュメントにあります

集計式はCoreDataではサポートされていません。

于 2011-05-26T21:30:21.763 に答える
2

Core Data SQLストアは、クエリごとに1対多の操作のみをサポートします。したがって、SQLストアに送信される述語には、、、、およびから1つの演算子(およびその演算子の1つのインスタンス)しか存在しない可能性がALLありANYますIN

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html

何が起こっている可能性があります:

  • 初期条件の1つがと評価されたTRUE場合、残りの条件は評価されないため、クラッシュは発生しません。
  • に到達しOR (ANY contactItems.FirstName contains[cd] '%@')、それTRUEが最初に使用された場合ANY、クラッシュは発生しません
  • に到達するとOR (ANY contactItems.LastName contains[cd] '%@')、2回目の使用が可能になりANYクラッシュが発生します

ANYを個別に実行し、場合によってはNSCompoundPredicateを使用して結果を組み合わせる必要があります。

于 2014-01-09T16:26:40.217 に答える
1

NSDecimalNumber経度をチェックしていた述語で同様の問題が見つかり、その一部がlongitude<-23発生し、obj_c_exception_throw詳細が表示されなくなりました。修正は、の後にスペースがあることを確認することでし<longitude < -23。それは基本的に<-一緒に何かのためにクラッシュしましたが、そうではありません>-

NSPredicateは、文書化されていない奇妙なエラーをスローします。

于 2012-11-23T20:33:21.467 に答える
1

LeadIDは万が一intプロパティですか?これと同じ問題が発生し、1つ以上のプロパティに検索語が含まれているかどうかを確認する述語を作成しました。ほとんどの場合は機能しましたが、ときどき、あなたと同じようにエラーで失敗します。

問題は、私がチェックしていたすべてのプロパティが1つを除いて文字列であったことでした。そのプロパティを述語から削除すると、すべてが正常に機能しました。

10076173は、データベース内のオブジェクトのLeadIDのint値であると思われます。Core Dataは通常、期待どおりにintをstringに変換するように見えますが、そうでない場合もあり、そのときにエラーが発生します。CONTAINS演算子は整数では意味がなく、クラッシュします。


さらなる証拠として、 CONTAINSの代わりにLIKEを使用するように述語を変更しようとしましたが、関連するエラーが発生し、最終的に何が起こっているのかがわかりませんでした。述語は

itemNumber LIKE "* test *" OR model LIKE "* test *" OR productDescription LIKE "* test *" [..snip ..]

例外は

「オブジェクト1008で正規表現マッチングを実行できません。」

その時点で、1008は見覚えがあることに気づきました...Int32であるitemNumberのように。


常にではありませんが、通常、CONTAINS演算子を使用すると、コアデータがintプロパティを文字列に変換する理由についてはわかりません。しかし、コンテキストが未保存の変更を行うまで、特にオブジェクトのto-manyリレーションシッププロパティが変更されるまで、述語が正常に機能したことを私は知っています。

于 2012-03-02T22:20:40.287 に答える
0

Core Dataのコレクションで同様の問題が発生したことを覚えているようです。この場合、フェッチ述語によってSQLが無効になりました(他のデータストアタイプは正常に機能しました)。これは理想的なソリューションではありませんが、オブジェクトが十分に少ない場合は、完全なフェッチを実行して、事後に結果セットをフィルタリングできます。

于 2011-05-26T20:25:14.007 に答える