简体   繁体   中英

UITableView methods are called before ViewDidLoad

I'm trying to create a simple weather app which gets data from OpenweatherMap using JSON and print them out in a UITableView. However, when I executed this code below and set a breakpoint at numberOfRowsInSection method, it returns 0 row. Somehow the viewDidLoad method was called after the numberOfRowsInSection method, that's why the threeHoursForecast array is empty. Can anyone help me on this please?

static NSString * const BaseURLString = @"http://api.openweathermap.org/data/2.5/forecast?q=Houston";

@interface HPViewController ()

@end

@implementation HPViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.threeHoursForecast = [[NSMutableArray alloc] init];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    [manager POST:BaseURLString parameters:nil
          success:^(AFHTTPRequestOperation *operation, id responseObject) {

              NSArray *data = [responseObject objectForKey:@"list"];

              for (NSDictionary *forecastPerThreeHours in data)
                  [self.threeHoursForecast addObject:[[forecastPerThreeHours valueForKey:@"main"] valueForKey:@"temp"]];
          }

          failure:^(AFHTTPRequestOperation *operation, NSError *error) {

              NSLog(@"Error: %@", error);
          }];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [self.threeHoursForecast count];
}

You can reload data after the completion handler is called, which will solve the problem.

[manager POST:BaseURLString parameters:nil
          success:^(AFHTTPRequestOperation *operation, id responseObject) {

              NSArray *data = [responseObject objectForKey:@"list"];

              for (NSDictionary *forecastPerThreeHours in data)
                  [self.threeHoursForecast addObject:[[forecastPerThreeHours valueForKey:@"main"] valueForKey:@"temp"]];

              //Add this line 
              [self.TableView reloadData];
          }

          failure:^(AFHTTPRequestOperation *operation, NSError *error) {

              NSLog(@"Error: %@", error);
          }];

The post method is async. You need to add [self.tableView reloadData]; in succes block of request.

manager POST: is asynchronous call, so you need to reload data after fetching JSON.

 [manager POST:BaseURLString parameters:nil
              success:^(AFHTTPRequestOperation *operation, id responseObject) {

                  NSArray *data = [responseObject objectForKey:@"list"];

                  for (NSDictionary *forecastPerThreeHours in data)
                      [self.threeHoursForecast addObject:[[forecastPerThreeHours valueForKey:@"main"] valueForKey:@"temp"]];

                  // [NOTE]
                  [self.tableView reloadData];
              }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM