itsclarke
itsclarke

Reputation: 8992

NSMutable array not retaining data after exiting function

I have a tableView that I'm trying to populate with data. I'm assigning values to an array within a function. Everything is saved up until up until it leaves the searchWithLocation function. Looking at the logs it makes me think that it has to do with ordering, like I'm not getting my data populated quick enough. Or maybe that's not the reason, I really have no idea.

- (void)viewDidLoad {
    [super viewDidLoad];

    venueName = [[NSMutableArray alloc] init];

    [YLPClient authorizeWithAppId:@"sdgsfgfgfg"
                           secret:@"aegsgdgdfs"
                completionHandler:^
     (YLPClient *client, NSError *error) {
         // Save your newly authorized client
         self.client = client;

         [self.client searchWithLocation:@"Chicago"
                       completionHandler:^
          (YLPSearch *search, NSError *error) {
              for (YLPBusiness *business in search.businesses) {
                  [venueName addObject:business.name];
              }
              NSLog(@"I return results: %lu", (unsigned long)[venueName count]);
          }];
         NSLog(@"I return 0: %lu", (unsigned long)[venueName count]);
     }];
}

...

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"number of rows in section: %lu", (unsigned long)[venueName count]);
    return [venueName count];
}

The logs:

2017-09-02 14:46:39.708 whatever[67890:8535793] number of rows in section: 0
2017-09-02 14:46:39.714 whatever[67890:8535793] number of rows in section: 0
2017-09-02 14:46:39.715 whatever[67890:8535793] number of rows in section: 0
2017-09-02 14:46:40.448 whatever[67890:8535846] I return 0: 0
2017-09-02 14:46:41.174 whatever[67890:8535846] I return results: 20

Upvotes: 0

Views: 45

Answers (1)

Amin Negm-Awad
Amin Negm-Awad

Reputation: 16660

You have a misunderstanding of asynchronous program execution. Every completion handler can be executed after the "calling" execution path is already terminated. In your case:

[self.client searchWithLocation:@"Chicago"
              completionHandler:
  // This completion handler can be executed after seconds, minutes or even hours.
  ^(YLPSearch *search, NSError *error) 
  {
    NSLog( @"As times go by – sometime in the future" );
    for (YLPBusiness *business in search.businesses) 
    {
      [venueName addObject:business.name];
    }
    NSLog(@"I return results: %lu", (unsigned long)[venueName count]);
  }];
  // This path is executed immediately. esp. likely before the cmpletion handler is executed
  NSLog( @"It is now or never" );
  NSLog(@"I return 0: %lu", (unsigned long)[venueName count]);

Move the code behind the completion handler inside it.

Upvotes: 1

Related Questions