2011-07-17 15 views
7

ユーザー入力に基づいて、私のNSMutableDictionaryをフィルタリングに取り組んでいる間、私は次のコードを作成しました:NSPredicate predicateWithFormat:(NSString *)inconsistency?

NSString *predicateString = [NSString stringWithFormat:@"SELF beginsWith[cd] %@", searchString]; 
NSPredicate *pred = [NSPredicate predicateWithFormat:predicateString]; 
NSArray *filteredKeys = [[myMutableDictionary allKeys] filteredArrayUsingPredicate:pred]; 

は「searchStringの」この定義にメソッドに渡されます。これは、しかし、が生じ

(NSString*) searchString 

次の例外を除いて:

... raise [valueForUndefinedKey:]:このクラスは キーには対応していませんY ...

修正があることが判明:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF beginsWith[cd] %@", searchString]; 
NSArray *filteredKeys = [[myMutableDictionary allKeys] filteredArrayUsingPredicate:pred]; 

私は理解していない、後者が働いている理由、および例外投げた元。私はkey value codingを少し読んだが、ここでどのように適用されるのか分からない。 (つまり、NSPredicateの定義方法を変更するだけで)誰かが私を啓発することはできますか?

更新: jtbandesのコメントに応じて、この問題をデモするためのTestAppプロジェクトを作成しました。 http://dl.dropbox.com/u/401317/TestApp1.tar.gz

+0

意味が分かると思うのであれば、実際には例外をすべて表示する必要があります。 – jtbandes

答えて

17

答えはin the predicate programming guideです。

文字列定数は、あなたは%@ ...を使用して変数置換を使用している場合は、両方が許容できる、... は、引用符が自動的に自動的に追加されている表現、単一および二重引用符でいる引用符で囲む必要があります。あなたはフォーマット文字列内の文字列定数を使用する場合は、あなたは

それらを自分の言葉を引用しなければならない[私の強調]

predicateWithFormatはあなたのために引用符を置きますが、stringWithFormatません。最初の例は、これを実行した場合にはおそらく動作します:

NSString *predicateString = [NSString stringWithFormat:@"SELF beginsWith[cd] '%@'", searchString]; 
//                   ^^ single or double quotes 
+0

実際、引用符で問題を解決しています。 "valueForUndefinedKey"例外をスローするだけで、開発者が間違ったパスをとらえているように思えるでしょう。 (無効な述語構文は私が思うと良いでしょう)多分objective-cの経験がないかもしれません。 – yanigisawa

+0

@ yanigisawa:それは無効な構文ではありません。引用符がない場合は、それがKVCキーであるとみなされるため、あるキーの値と別のキーの値を比較します。そのような状況下では、例外は理にかなっています。 – JeremyP

+0

申し訳ありませんが、私はこれらのコンパイラとランタイムエラーで熟練していない人までそれをチョークします。ご協力いただきありがとうございます。 – yanigisawa