NSPredicate and Arrays

I have a short question. I have an NSArray populated with Cars (which inherits from NSObject). Car has @property NSString *engine (also considered @synthesize )

Now I want to filter the array using NSPredicate :

 predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(engine like %@)", searchText]]; newArray = [ArrayWithCars filteredArrayUsingPredicate:predicate]; 

This causes a valueForUndefinedKey error. Is predicateWithFormat right?

Thank you for your responses.

+2
source share
4 answers

Here is the real reason it doesn't work:

When you create a string using stringWithFormat: it will look like this:

 @"engine like searchText" 

Then you pass it to predicateWithFormat: which will see that both the left side and the right side of the comparison are unquoted strings, which means that it will interpret them as if they were key.

When this code runs, it will do:

 id leftValue = [object valueForKey:@"engine"]; id rightValue = [object valueForKey:@"searchText"]; return (leftValue is like rightValue); 

An exception caused by the fact that your object complains that it does not have a method named "searchText", which is correct.

Contrast this if you pulled out a call to stringWithFormat: and just put everything directly into predicateWithFormat: ::

 NSPredicate *p = [NSPredicate predicateWithFormat:@"engine like %@", searchText]; 

predicateWithFormat: smart. He sees "the replacement pattern aha, a %@ ! This means that I can infer the argument from the argument list and paste it into the field and use it as is." This is exactly what he is going to do. It is going to infer the value of searchText from the argument list, put it in NSExpression and paste it directly into the parsing tree.

The most interesting thing is that the expression he expresses will be an expression of a constant value. This means that it is a literal meaning; not a key path, not a collection, etc. This will be a literal string. Then, when your predicate works, it will do:

 id leftValue = [object valueForKey:@"engine"]; id rightValue = [rightExpression constantValue]; return (leftValue is like rightValue); 

And this is correct, and therefore you should not pass stuff via stringWithFormat: before passing it to predicateWithFormat:

+4
source

k, I found an error.

 predicate = [NSPredicate predicateWithFormat:@"engine like *%@*", searchText]; 

works correctly. ** absent. In addition, your searchText should be uppercase.

@Josuhua is not real code, just to visualize my problem

+3
source

Firstly, your code is more detailed than necessary, which always opens up the possibility for you to make a mistake. Try:

 predicate = [NSPredicate predicateWithFormat:@"engine like %@", searchText]; 

Secondly, "ArrayWithCars" looks like a class name (by convention, classes start with an uppercase). Is this a class or an incorrectly named local variable (for example: "arrayWithCars" or just "cars")?

Third, what kind of mistake? Which key is undefined? Do not rephrase errors when asking others for help - we cannot see what you see if you do not show us.

+2
source

Try using the link . You can know various ways to use NSPredicate.

+1
source

All Articles