Why doesn't this simple NSPredicate filter my array

263 views Asked by At

I have a very simple NSPredicate that's supposed to filter my array of custom objects.

NSLog(@"%@", self.displayedSources);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchText];
[self.displayedSources filterUsingPredicate:predicate];
NSLog(@"%@", self.displayedSources);

However, this leaves me with 0 results (even with empty searchText).

I know the array is populated with 26 objects of custom type, where the header looks like so

@interface NewsSourceObject : NSObject <NSCoding>
@property (nonatomic, copy,   readonly) NSString *objectId;
@property (nonatomic, copy,   readonly) NSString *name;
...
@end

I know the code is being executed, because I've added print statements logging the length of the array both before and after applying the predicate (26 - 0).

I've been pulling my hair out for over half a day with this, because I can't tell what's wrong.

EDIT 1: I tried logging the contents of the array before and after applying the predicate (see top code block) using this description method for the objects:

- (NSString *)description {
  return [NSString stringWithFormat:@"%@", self.name];
}

And this is what I get:

2015-06-08 02:57:28.521 Newsloop[8554:1578121] (
  "ABC News",
  "BBC News",
  "Bleacher Report",
  "Business Insider",
  "BuzzFeed News",
  CNN,
  "Daily Mail Online",
  ...
)
2015-06-08 02:57:28.522 Newsloop[8554:1578121] (
)
1

There are 1 answers

1
Matthias Bauch On BEST ANSWER

Wild speculation, but my theory is that you don't "reset" self.displayedSources after running the filter. Since you filter the array in place one wrong keystroke clears the array forever.

You probably run that part of code while searchText still contains the empty string. Which basically removes all your objects from the array. Every consecutive key stroke runs a filter on the empty array.

Store the filtered array in a different variable instead:

NSLog(@"%@", self.displayedSources);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchText];

NSArray *filtered = [self.displayedSources filteredArrayUsingPredicate:predicate];

NSLog(@"%@", filtered);