在我看来,我试图显示一些与天气有关的信息。我用
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
Make NSURL and other related things
Send NSURLRequest
Set 2 UILabels to data
NSLog(Show data retrieved)
});
出于某种原因,我在uilabel更改为新文本之前大约15-45秒看到NSLog行。我是Obj-C的新手,我的很多代码来自于使用教程,所以我对dispatch_async方法没有最好的理解。任何想法或建议将不胜感激。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURLResponse *response = nil;
NSError *error = nil;
NSData *respData = nil;
NSURLRequest *forecastRequest = [NSURLRequest requestWithURL:currentForecastUrl];
respData = [NSURLConnection sendSynchronousRequest:forecastRequest returningResponse:&response error:&error];
[_responseData appendData:respData];
NSLog(@"Response: %@", response);
NSLog(@"Error: %@", error);
id JSON = [_responseData yajl_JSON];
currentForecast = [[NSArray alloc]initWithObjects:[JSON objectForKey:@"temperature"],[JSON objectForKey:@"feelsLike"],nil];
[_temperatureLabel setText:[NSString stringWithFormat:@"%@",[JSON objectForKey:@"temperature"]]];
[_tempDescriptionLabel setText:[NSString stringWithFormat:@"%@",[JSON objectForKey:@"desc"]]];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
[_tempDescriptionLabel setAlpha:1];
[_temperatureLabel setAlpha:1];
[UIView commitAnimations];
NSLog(@"Done");
NSLog(@"JSON: %@", [JSON yajl_JSONStringWithOptions:YAJLGenOptionsBeautify indentString:@" "]);
});
答案 0 :(得分:2)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
用于创建后台线程,但应在主线程
中更新用户界面 像这样:dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//do stuff in background
dispatch_async(dispatch_get_main_queue(), ^{
// Update your UI
});
});
答案 1 :(得分:1)
所有“使用主队列”的答案都很好。但请注意,NSURLConnection会为您完成所有这些。
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// this happens on the main thread because we passed mainQueue
}];
编辑:这是您的代码,除了较小且具有现代语法。它应该做同样的工作。为了好玩,剪切并粘贴它。
// 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;
}];
}];
为我删除代码是编程中最令人愉快的部分。最容易阅读的代码行,执行速度最快,不需要测试的是不存在的行。
答案 2 :(得分:0)
您的问题是因为您尝试从主线程更新UILabel
。之前我已经看到了确切的症状,其中更新主线程的UI元素仍然更新它们,但是延迟很长。因此,只要您有一个以这种方式运行的UI元素,请检查以确保它在主线程上执行。
答案 3 :(得分:0)
我很惊讶这段代码可以正常工作,因为你正在后台线程上更新标签。你想沿着这些方向做点什么:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^{
//Make NSURL and other related things
//Send NSURLRequest
dispatch_async(dispatch_get_main_queue(), ^{
// Set your UILabels
});
});