问题
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.
来源:https://stackoverflow.com/questions/38025015/code-not-completing-before-next-method-is-called