后台子线程(非主线程)更新UI引起的警告

一、问题描述

-(void)sendAsynchronousRequest
{
NSLog(@"%@",[NSThread currentThread]);
[SVProgressHUD showWithStatus:@"正在登录....." maskType:SVProgressHUDMaskTypeBlack];
NSString *urlString = [NSString stringWithFormat:@"http://120.25.226.186:32812/login?username=%@&pwd=%@&type=JSON",self.userName.text,self.userPWD.text];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSOperationQueue *operationQueue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSString *jsonString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSRange rangeStart = [jsonString rangeOfString:@"\":\""];
NSUInteger start = rangeStart.location+;
NSRange rangeEnd = [jsonString rangeOfString:@"\"}"];
NSUInteger end = rangeEnd.location;
NSUInteger length = end-start;
NSString *message =[jsonString substringWithRange:NSMakeRange(start, length)];
if([jsonString containsString:@"success"])
{
NSLog(@"%@",[NSThread currentThread]);
[SVProgressHUD showSuccessWithStatus:message maskType:SVProgressHUDMaskTypeBlack];
}
else
{
        NSLog(@"%@",[NSThread currentThread]);
[SVProgressHUD showSuccessWithStatus:message maskType:SVProgressHUDMaskTypeBlack];
}
}];
}

运行时发生以下警告:

This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.

二、问题分析

此应用程序是由一个后台线程修改布局,从而导致崩溃,将导致在未来的版本异常。

更新UI必须在主线程。调用NSURLConnection的sendAsynchronousRequest: queue: completionHandler:方法会创建子线程执行请求,而在Block回调中调用的是主线程SVProgressHUD对象,从而导致错误。通过[NSThread currentThread]打印前后线程,前者在主线程:<NSThread: 0x7fbac9c074e0>{number = 1, name = main},后者在子线程<NSThread: 0x7fbacc0208a0>{number = 3, name = (null)}。

三、问题解决

例如:GCD代码

dispatch_async(dispatch_get_main_queue(), ^{
  // 更UI
});

修改如下:

-(void)sendAsynchronousRequest
{
NSLog(@"%@",[NSThread currentThread]);
[SVProgressHUD showWithStatus:@"正在登录....." maskType:SVProgressHUDMaskTypeBlack];
NSString *urlString = [NSString stringWithFormat:@"http://120.25.226.186:32812/login?username=%@&pwd=%@&type=JSON",self.userName.text,self.userPWD.text];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSOperationQueue *operationQueue = [[NSOperationQueue alloc]init]; [NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSString *jsonString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSRange rangeStart = [jsonString rangeOfString:@"\":\""];
NSUInteger start = rangeStart.location+;
NSRange rangeEnd = [jsonString rangeOfString:@"\"}"];
NSUInteger end = rangeEnd.location;
NSUInteger length = end-start;
NSString *message =[jsonString substringWithRange:NSMakeRange(start, length)];
if([jsonString containsString:@"success"])
{
NSLog(@"%@",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD showSuccessWithStatus:message maskType:SVProgressHUDMaskTypeBlack];
});
}
else
{
NSLog(@"%@",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD showSuccessWithStatus:message maskType:SVProgressHUDMaskTypeBlack];
});
}
}];
}
上一篇:Android之自定义checkbox样式


下一篇:浅谈java中异常抛出后代码是否会继续执行