3

predicateWithFormat:NSPredicateのメソッドを使用した(私にとって)奇妙なケースがあります。

以下を使用して、2つのNSPredicateインスタンスの説明をコンソールに記録します。

NSNumber *myNumber = [NSNumber numberWithInt:1];

NSString *predicateFormatByHand = [NSString stringWithFormat:@"self MATCHES 'chp%@_img[0-9]+\\.png'", myNumber];
NSPredicate *firstPredicate = [NSPredicate predicateWithFormat:predicateFormatByHand];

NSLog(@"firstPredicate description: %@", firstPredicate);

NSPredicate *secondPredicate = [NSPredicate predicateWithFormat:@"self MATCHES 'chp%@_img[0-9]+\\.png'", myNumber];

NSLog(@"secondPredicate description: %@", secondPredicate);

これは以下を出力します:

 firstPredicate description: SELF MATCHES "chp1_img[0-9]+.png"
secondPredicate description: SELF MATCHES "chp%@_img[0-9]+.png"

これらの説明は同じだと思います。

誰かがなぜそうではないのか説明できますか?

この質問に続いて、埋め込まれた一重引用符のさまざまなエスケープシーケンスを試してみましたが、そうするときは、NSPredicateがフォーマット文字列を解析できないと文句を言い続けます。何が起こっているのかを知っていただければ幸いです。)

更新:1つの回答は、intではなくNSNumberの使用に問題があることを示唆しているため、次のようになります。

NSPredicate *thirdPredicate = [NSPredicate predicateWithFormat:@"self MATCHES 'chp%d_img[0-9]+\\.png'", [myNumber intValue]];

NSLog(@"thirdPredicate description: %@", thirdPredicate);   

私はもともとこれから始めましたが、残念ながら出力は同じです:

thirdPredicate description: SELF MATCHES "chp%d_img[0-9]+.png"

(何かがフォーマット指定子が評価されていないことを意味します。)

4

3 に答える 3

4

答えは簡単です。によって使用されるパーサーNSPredicateは、引用符内のすべてが文字列リテラルであると想定し、その内容を置換しようとはしません。動的な文字列値が必要な場合は、最初の例のように、述語形式の文字列に置き換える前に文字列を作成する必要があります。

于 2012-08-19T12:57:41.177 に答える
2

...というのpredicateはそういうものではないからstringです。

いずれの場合も、predicate2つのフォーマット指定子を100%安全にのみ使用する必要があります。

  • キー用に1つ(%K); と
  • 用に1つ(%@);

キーも、に追加するときにフォーマットすることはできませんpredicatepredicatesこれが、2番目(および3番目)が値内でフォーマットされていない理由です。

次のように追加する前に、 をフォーマットできます。predicate

NSNumber *myNumber = [NSNumber numberWithInt:1];
NSString *string = [NSString stringWithFormat:@"chp%@_img[0-9]+\\.png", myNumber];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", string];
NSLog(@"%@", predicate);

結果は次のとおりです。

SELF MATCHES "chp1_img[0-9]+\\.png"

...そして私の最初の文を決して忘れないでください:predicatesstringsは同じものではありません。

于 2012-08-19T12:31:49.407 に答える
0

私の解釈

%@は、オブジェクト値のvararg置換です

「述語プログラミングガイド」では、CoreData%@オブジェクトと比較できる値を置き換えるためにのみ使用できます。例えば

NSNumber *myNumber = [NSNumber numberWithInt:1]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"count = %@", myNumber];

「count」がエンティティのNumber属性である場合、は完全に有効です。これは、SQLiteのプリペアドステートメントに値をバインドするのと似ています。

述語の一般的な文字列フォーマットに使用できる場合は、2つの異なるフォーマット指定子 、およびキーパスと値を%@指定する必要はありません。%K%@

于 2012-08-19T11:44:16.187 に答える