All the "use the main queue" answers are good. But please notice that NSURLConnection does all this for you.
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// this happens on the main thread because we passed mainQueue
}];
EDIT: Here's your code, except smaller and with modern syntax. It should do exactly the same job. For fun, cut and paste this in.
// it assumes the following variables in scope
NSURL *currentForecastUrl;
__block NSArray *currentForecast;
UILabel *_temperatureLabel, *_tempDescriptionLabel;
// start counting lines here
NSURLRequest *forecastRequest = [NSURLRequest requestWithURL:currentForecastUrl];
[NSURLConnection sendAsynchronousRequest:forecastRequest queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// I cheated a little on lines, because we really ought to check errors
// in here.
NSError *parseError; // use native JSON parser
id parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
currentForecast = @[parse[@"temperature"], parse[@"feelsLike"]]; // note the array and dictionary literal syntax
_temperatureLabel.text = parse[@"temperature"]; // if these are ivars, I reccomend using self.temperatureLabel, not _temp...
_tempDescriptionLabel.text = parse[@"desc"];
[UIView animateWithDuration:2.0 animations:^{ // use UIView animation block
_temperatureLabel.alpha = 1.0;
_tempDescriptionLabel.alpha = 1.0;
}];
}];
Deleting code for me is the most pleasurable part of programming. The line of code that's easiest to read, executes the quickest and requires no testing is the line that isn't there.