Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSPredicate crash on CONTAINS?

I'm trying to do a simple predicate filter on an array of objects.

The objects in the array have 2 properties, displayValue and value. I am trying to filter based on a search string and I get a crash.

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"displayValue CONTAINS[cd] %@", searchString];
    NSArray *results = [_data filteredArrayUsingPredicate:pred];

what exactly is incorrect about this format that it causes a Can't use in/contains operator with collection 100 (not a collection) crash?

like image 836
JMD Avatar asked Jan 24 '26 04:01

JMD


1 Answers

I was able to reproduce your problem. This happens if the displayValue of one of the objects is not a NSString, but some different type.

From your error message, I assume that you assigned an NSNumber, for example

obj.displayValue = @100;

somewhere in your code. The "CONTAINS" predicate works only with strings, so you must assign only string values to the property.

Therefore, you should define the type of the property as NSString * instead of id, and check the assignments to that property.

If you really need to keep the id type and store different kinds of objects in that property, then you cannot use the "CONTAINS" operator in the predicate. A direct comparison with @"displayValue == %@" would work, however.

UPDATE: As a workaround, you could use the description method, which converts any object to a string, in particular it converts a NSNumber to its string representation. So the following could work:

[NSPredicate predicateWithFormat:@"displayValue.description CONTAINS[cd] %@", searchString];

The drawback is that the exact description format is not documented.

Another solution could be to use a block-based predicate, where you can check the type of each object and perform the appropriate comparison.

like image 161
Martin R Avatar answered Jan 26 '26 16:01

Martin R



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!