2009-09-16 11 views
5

私はiPhoneのCoreDataはIN述語をサポートしていますか?

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (type IN {71, 73, 70, 72, 74})' 
...実行すると、executeFetchRequestメッセージが例外をスローします... ...ユーザーによって定義されたタイプのリストに基づいて、特定のタイプのレコードの束を取得するために

[fetchRequest setEntity:[NSEntityDescription entityForName:@"myRecord" inManagedObjectContext:self.managedObjectContext]]; 
NSSet *shipTypes = [NSSet setWithObjects:[NSNumber numberWithInt:70], 
        [NSNumber numberWithInt:71], 
        [NSNumber numberWithInt:72], 
        [NSNumber numberWithInt:73], 
        [NSNumber numberWithInt:74], 
        nil]; 
NSPredicate *aPredicate = [NSPredicate predicateWithFormat:@"type in %@", shipTypes]; 
[fetchRequest setPredicate:aPredicate]; 
theRecords = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

をしようとしています

私は間違ったことをしましたか、これは本当にサポートされていませんか?

+1

それは動作するはずですが、私は私の人生のためになぜそれができないのか理解できません。述語フォーマット文字列構文文書を読み、何かを見つけることができるかどうかを見てください:http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html – Tim

+0

合意。あなたはNSSetの代わりにNSArrayを試すかもしれませんが、それは書かれたとおりに動作するはずです。 –

+2

もしあなたがそれをうまく動作させるなら、正しい答えの一つをマークするべきです。 –

答えて

15

NSArrayを使用しなければならないと私は思っていますが、NSArrayが受け入れられるならば、順序はそれほど重要ではない(明らかにSQLの実行速度に影響するかもしれないが) 。

補足として、+ predicateWithFormat:callはコンパイル時の正当性や型チェックを行うことができないため、これまでどんなコードでも使用していません。私は非常に個々のクラスを使用することをお勧めします。この場合

、私は思います。これは、コンパイル時に、この特定のエラーをキャッチしているだろうが、それは潜在的にNSExpressionレベルでそれをキャッチしなければならず、これには非常に明確になっていることを

fetchRequest.entity = [NSEntityDescription entityForName:@"myRecord" inManagedObjectContext:self.managedObjectContext]]; 

NSArray *shipTypes = [NSArray arrayWithObjects:[NSNumber numberWithInt:70], 
             [NSNumber numberWithInt:71], 
             [NSNumber numberWithInt:72], 
             [NSNumber numberWithInt:73], 
             [NSNumber numberWithInt:74], 
             nil]; 
fetchRequest.predicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:@"type"] rightExpression:[NSExpression expressionForConstantValue:shipTypes] modifier:NSDirectPredicateModifier type:NSInPredicateOperatorType options:0]; 

theRecords = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

ありません何が悪かったのか。

+0

NSSetではなくNSArrayを使用して動作します。これをキャッチすることに感謝します。 –

0

うーんへのあなたの述語を変更してみてください。私は両方のANYキーワードを追加し、NSArrayを使用してみました。実際に私はNSAArrayを使用して、コアデータからこの例外が発生したときに開始しました。振り返ってみると、2つの式をANDで結合していたため、Core Dataの問題でした。 (私は、私は戻って、このことを確認する必要があります知っているが、この記事を読みながら、この考えはちょうど、私に発生しました。)ここに私の元の式である:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"BPM BETWEEN { %d, %d } AND GENRE IN %@", lower, upper, genres]; 

私の解決策は2つの部分にそれを破ることでした。さて、述語を使ってBPMのクエリを発行しますが、結果の配列をとり、-filteredArrayUsingPredicateを@ "genre IN%@"で使用します。したがって:

array = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"genre IN %@", genres]]; 

これは私のために働いています。

0

私はこれで苦労しました。最終的に私はそれぞれのセットのサブ述語を終わらせました。

したがって、たとえば:そのタイプを想定しています

NSMutableArray *subpredicates = [NSMutableArray array]; 

NSArray *shipTypes = [NSArray arrayWithObjects:[NSNumber numberWithInt:70], 
            [NSNumber numberWithInt:71], 
            [NSNumber numberWithInt:72], 
            [NSNumber numberWithInt:73], 
            [NSNumber numberWithInt:74], 
            nil]; 

for (NSNumber *num in shipTypes) { 
    [subpredicates addObject:[NSPredicate predicateWithFormat:@"ANY type == %@", num]];   
} 

NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]; 

はNSSetです。それはあなたが持っていない場合:

for (NSNumber *num in shipTypes) { 
    [subpredicates addObject:[NSPredicate predicateWithFormat:@"type == %@", num]];   
} 
関連する問題