これが機能しない本当の理由は次のとおりです。
を使用して文字列を作成すると、次stringWithFormat:
のようになります。
@"engine like searchText"
に渡すとpredicateWithFormat:
、比較の左側と右側の両方が引用符で囲まれていない文字列であることがわかります。つまり、それらがkeypathsであるかのように解釈されます。
このコードが実行されると、次のようになります。
id leftValue = [object valueForKey:@"engine"];
id rightValue = [object valueForKey:@"searchText"];
return (leftValue is like rightValue);
スローされる例外は、正しい「searchText」という名前のメソッドがないことを訴えるオブジェクトです。
stringWithFormat:
これを、呼び出しを取り、すべてを に直接入れた場合とは対照的ですpredicateWithFormat:
。
NSPredicate *p = [NSPredicate predicateWithFormat:@"engine like %@", searchText];
predicateWithFormat:
賢いです。「あはは、%@
置換パターン! これは、引数リストから引数をポップして、ボックスに入れ、そのまま使用できることを意味します」と表示されます。それはまさにそれがしようとしていることです。searchText
引数リストからの値をポップし、 でボックスNSExpression
化し、解析された式ツリーに直接挿入します。
ここで最も興味深いのは、作成される式が定数値式になることです。これは、リテラル値であることを意味します。キーパスやコレクションなどではありません。リテラル文字列になります。次に、述語が実行されると、次のようになります。
id leftValue = [object valueForKey:@"engine"];
id rightValue = [rightExpression constantValue];
return (leftValue is like rightValue);
それは正しいです。また、stringWithFormat:
に渡す前に何かを渡してはならない理由でもありますpredicateWithFormat:
。