-1

This is my array

@property (nonatomic, strong) NSMutableArray *searchResults;

I initialized it in viewDidLoad function. I want to remove all objects from this array when current input in search bar is changed and add populate it using new elements. But when I do

[self.searchResults removeAllObjects];

It won't add new elements. same goes with returning an array to self.searchResults

But when I don't remove elements from an array and append elements, it adds elements with no problem. I'm really having a hard time figuring out what's wrong.

viewDidLoad func

- (void) viewDidLoad {
[super viewDidLoad];
self.searchBar.delegate = self;
self.searchBar.showsCancelButton = YES;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.searchResults = [[NSMutableArray alloc] init];
[self searchHandler:self.searchBar];
}

here is adding new elements.

- (NSMutableArray *)getProductList: (NSString *)text withArray: (NSMutableArray *) arrayResult{
[self.searchResults removeAllObjects];
[manager POST:url parameters:parameter
        success:^(AFHTTPRequestOperation *operation, id responseObject){
            NSLog(@"Length: %lu", (unsigned long)[responseObject count]);
            int length = [responseObject count];
            NSString *key;
            for (int i=0; i<length; i++) {
                key = [NSString stringWithFormat:@"%d", i];
                [self.searchResults addObject:responseObject[key]];
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", error);
        }];
}

checking the array

- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
    NSLog(@"changed text: %@", searchText);
    //[searchResults removeAllObjects];
    self.searchResults = [self getProductList:searchText withArray:self.searchResults];
    NSLog(@"Length of current array: %lu", (unsigned long)[self.searchResults count]);
    for (NSString *item in self.searchResults) {
        NSLog(@"%@", item);
    }
    [self.tableView reloadData];
 }
  • are you sure that this: `responseObject[key]` is returning something meaningful ? – Julian Sep 08 '14 at 18:00
  • @JulianKról yes. It's returning some strings. – Chrome user Sep 08 '14 at 18:01
  • self.searchResults is it not nil while trying to add something? – Julian Sep 08 '14 at 18:02
  • @JulianKról I checked it. it's not nil. – Chrome user Sep 08 '14 at 18:05
  • then it is weird, looks like you are not telling us the full story :) – Julian Sep 08 '14 at 18:07
  • `searchResults` is `nil` and never had anything in it to begin with. – Hot Licks Sep 08 '14 at 18:12
  • I tried initializing it in init function that I overwritten and viewDidLoad function. Also checked it whether its nil or not in searchbar event listener function. Also I tried adding object to the array without removeAllObjects message and it was adding objects. @HotLicks – Chrome user Sep 08 '14 at 18:17
  • It's nil, trust me. Stupid question: How many different places do you do `[[MyViewController alloc] init...]`? – Hot Licks Sep 08 '14 at 18:19
  • Remember, Objective-C will silently ignore a nil pointer in many circumstances. – Hot Licks Sep 08 '14 at 18:20
  • @HotLicks only once in another view controller that has scroll view to jump between 2 view controllers. I also tried initializing in the latter function, which is basically called on every time when change occurs in search bar. – Chrome user Sep 08 '14 at 18:22
  • So nowhere do you create an instance of the class so you can set/access one of its properties? – Hot Licks Sep 08 '14 at 18:23
  • There is an instance of the class in another view controller which is called when application is started. @HotLicks – Chrome user Sep 08 '14 at 18:30
  • Where are you inspecting `searchResults` to determine that nothing is being added? – jscs Sep 08 '14 at 18:31
  • You understand that if you create two different instances of the same class, they do not magically "share" the same properties, but each has it's own set. You can't initialize a property in one instance and then operate on that property in another instance. – Hot Licks Sep 08 '14 at 18:32
  • I'm betting on a different common problem than you are, @HotLicks: not understanding that the completion Block is asynchronous and looking at the array immediately after the `POST:parameters:success:failure:` call. – jscs Sep 08 '14 at 18:33
  • @JoshCaswell - Yep, that's another possibility. He doesn't log immediately after setting values into the array so we have no indication what's going on. – Hot Licks Sep 08 '14 at 18:36
  • @JoshCaswell I added how I checked the array. – Chrome user Sep 08 '14 at 18:37
  • Okay, now how does that connect to the other snippet? – jscs Sep 08 '14 at 18:37
  • @JoshCaswell they are methods of one class and getProductList is called every time when there is a change in searchbar input. getProductList removes all previous objects from the array and add new elements to that array. – Chrome user Sep 08 '14 at 18:43

1 Answers1

0

You set searchResults

  self.searchResults = [self getProductList:searchText withArray:self.searchResults];

But getProductList doesn't return an array. Aren't you getting a warning? If not, I suspect you are just setting it to nil on the return

Also, getProductList is asynchronous, but you are just trying to load table data as soon as it returns.

Do something more like this instead:

- (NSMutableArray *)getProductList: (NSString *)text withArray: (NSMutableArray *) arrayResult{
[self.searchResults removeAllObjects];
[manager POST:url parameters:parameter
        success:^(AFHTTPRequestOperation *operation, id responseObject){
            NSLog(@"Length: %lu", (unsigned long)[responseObject count]);
            int length = [responseObject count];
            NSString *key;
            for (int i=0; i<length; i++) {
                key = [NSString stringWithFormat:@"%d", i];
                [self.searchResults addObject:responseObject[key]];
            }

            [self.tableView reloadData];

        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", error);
        }];
}


- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
  [self getProductList:searchText withArray:self.searchResults];    
}

This should be cleaned up more (remove the withArray parameter -- you don't even use it).

Just make sure self.searchResults is not nil at this point.

Lou Franco
  • 87,846
  • 14
  • 132
  • 192
  • I tried initializing new array and assigning to self.searchResults but it still didn't work. I directly removed elements from the array in function as well. – Chrome user Sep 08 '14 at 18:46
  • 1
    The function `getProductList:withArray` isn't returning anything -- don't assign to `searchResults` in `searchBar:textDidChange:` That whole function is a mess -- you pass in the output array (arrayResult), you update self.searchResults directly, and you expect to return an array. Pick one of those. – Lou Franco Sep 08 '14 at 18:52
  • Oh I should've just added [self.tableView reloadData] after adding elements. Thanks!!! – Chrome user Sep 08 '14 at 18:56
  • AND AND AND -- don't overwrite `self.searchResults` by assigning the return (when you don't return anything) – Lou Franco Sep 08 '14 at 18:57
  • yeah. I changed it to void now. – Chrome user Sep 08 '14 at 18:59