Вот реальная причина, почему она не работает:
Когда вы строите строку, используя 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:
.