我正在尝试从本地节点服务器中提取一些数据。服务器获取get请求并记录它,但由于某种原因,我的iOS应用程序将不会执行我在完成处理程序中的任何代码。这是代码:
- (IBAction) buttonPressed{
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:3000/"];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithURL:url
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error){
nameLabel.text = @"yay!";
/*
if (!error){
nameLabel.text = @"noerr";
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
if (httpResp.statusCode == 200){
NSError *jsonErr;
NSDictionary *usersJSON =
[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&jsonErr];
if (!jsonErr){
// nameLabel.text = usersJSON[@"username"];
nameLabel.text = @"nojerr";
}
else{
nameLabel.text = @"jsonErr";
}
}
}
else{
nameLabel.text = @"Err";
}
*/
}];
[dataTask resume];
}
运行程序时,nameLabel不会更改为“yay”。但是,如果我尝试在NSURLSessionDataTask行之前更改nameLabel,则会更改。
答案 0 :(得分:14)
NSURLSessionDataTask
在后台线程中运行。要更新用户界面中的任何内容,例如标签,按钮,表视图等,您必须在主线程上执行此操作。如果要更新completionHandler
块中的标签文本,则需要更新主线程中的标签,如下所示:
dispatch_sync(dispatch_get_main_queue(), ^{
nameLabel.text = @"yay!";
});
答案 1 :(得分:13)
试试这个魔法:
static NSURLSession* sharedSessionMainQueue = nil;
if(!sharedSessionMainQueue){
sharedSessionMainQueue = [NSURLSession sessionWithConfiguration:nil delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
}
NSURLSessionDataTask *dataTask =
[sharedSessionMainQueue dataTaskWithURL:url completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error){
//now will be on main thread
}];
[dataTask resume];
这为您提供了NSURLConnection的原始行为以及主线程上的完成处理程序,因此您可以安全地更新UI。但是,假设您要解析下载或执行一些繁重的处理,在这种情况下,您可能会受益于操作队列后台线程上的完成处理程序,然后将dispatch_sync作为最后一步使用主线程。 / p>