Code Not Completing Before Next Method Is Called

2019-01-29 10:07发布

问题:

In my iOS app, I am using the forecast.io API to get a weather forecast for 3 specific days. Once I get the array from all 3, I want to create an NSMutableArray and add all of those objects to it. The problem I am getting is that it is trying to create the NSMutableArray before the forecast data is retrieved. Here is what I have so far:

typedef void(^myCompletion)(BOOL);
-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:YES];
    [self myMethod:^(BOOL finished) {
        if(finished){
            NSMutableArray *allOfIt = [[NSMutableArray alloc] initWithObjects:self.weatherSaturday, self.weatherSunday, self.weatherMonday, nil];
            NSLog(@"%@", allOfIt);
        }
    }];

}
-(void) myMethod:(myCompletion) compblock{
    //do stuff
    ForecastKit *forecast = [[ForecastKit alloc] initWithAPIKey:@"MY-API-KEY"];
    // Request the forecast for a location at a specified time
    [forecast getDailyForcastForLatitude:37.438905 longitude:-106.886051 time:1467475200 success:^(NSArray *saturday) {

    //    NSLog(@"%@", saturday);
        self.weatherSaturday = saturday;


    } failure:^(NSError *error){

        NSLog(@"Daily w/ time %@", error.description);

    }];

    [forecast getDailyForcastForLatitude:37.438905 longitude:-106.886051 time:1467561600 success:^(NSArray *sunday) {

        //  NSLog(@"%@", sunday);
        self.weatherSunday = sunday;

    } failure:^(NSError *error){

        NSLog(@"Daily w/ time %@", error.description);

    }];

    [forecast getDailyForcastForLatitude:37.438905 longitude:-106.886051 time:1467648000 success:^(NSArray *monday) {

        // NSLog(@"%@", monday);
        self.weatherMonday = monday;

    } failure:^(NSError *error){

        NSLog(@"Daily w/ time %@", error.description);

    }];

    compblock(YES);
}

When the code is ran, it fires the NSLog for allOfIt, which shows as null, before it gets any of the forecast data. What am I missing?

回答1:

The problem I am getting is that it is trying to create the NSMutableArray before the forecast data is retrieved

Yup, exactly. The problem is simply that you don't understand what "asynchronous" means. Networking takes time, and it all happens in the background. Meanwhile, your main code does not pause; it is all executed instantly.

Things, therefore, do not happen in the order in which your code is written. All three getDailyForcastForLatitude calls fire off immediately and the whole method ends. Then, slowly, one by one, in no particular order, the server calls back and the three completion handlers (the stuff in curly braces) are called.

If you want the completion handlers to be called in order, you need each getDailyForcastForLatitude call to be made in the completion handler of the getDailyForcastForLatitude call that precedes it. Or, write your code in such a way that it doesn't matter when and in what order the completion handlers come back to you.