后台子线程(非主线程)更新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];
});
}
}];
}
后台子线程(非主线程)更新UI引起的警告的更多相关文章
- Android 快速切换到主线程更新UI的几种方法
此最近看了网上,在子线程更新UI的方法,说法很多,但都不是很全面.在此我争取做到总结的全面一些,希望以后对自己,对大家都有一些帮助. 方法一: view.post(Runnable action) 假 ...
- 一定要在主线程更新UI
在一些技术交流群里面,一些初学者(我表示我也是其中一人),总是会发现,为什么我UIView的animate方法,不会动!而是直接闪? 这是为什么呢? 一定要在主线程中更新UI! 一定要在主线程中更新U ...
- 在非主线程中更新UI
在非主线程中调用了showMessage方法,结果报错:Can't create handler inside thread that has not called Looper.prepare() ...
- Android 在非主线程无法操作UI意识
Android在应用显示Dialog是一个非常easy事儿,但我从来没有尝试过Service里面展示Dialog. 经验UI操作要在主线程,本地的服务Service是主线程里没错,可是远程servic ...
- 开子线程下载图片,回到主线程刷新UI步骤
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [NSThread detachN ...
- WPF里面多线程访问UI线程、主线程的控件
如果出现以下错误:调用线程无法访问此对象,因为另一个线程拥有该对象. 你就碰到多线程访问UI线程.主线程的控件的问题了. 先占位.
- 在非主线程里面使用NSTimer创建和取消定时任务
为什么要在非主线程创建NSTimer 将 timer 添加到主线程的Runloop里面本身会增加线程负荷 如果主线程因为某些原因阻塞卡顿了,timer 定时任务触发的时间精度肯定也会受到影响 有些定时 ...
- [转]QT子线程与主线程的信号槽通信-亲测可用!
近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号槽 ...
- ThreadLocal ——android消息机制handler在非主线程创建not called Looper.prepare() 错误的原因
引用自:https://www.jianshu.com/p/a8fa72e708d3 引出: 使用Handler的时候,其必须要跟一个Looper绑定.在UI线程可直接初始化Handler来使用.但是 ...
- Qt自己定义事件实现及子线程向主线程传送事件消息
近期在又一次学习Qt的时候,由于要涉及到子线程与主线程传递消息,所以便琢磨了一下.顺便把有用的记录下来,方便自己以后查询及各位同仁的參考! 特此声明,本篇博文主要讲述有用的,也就是直接说明怎么实现,就 ...
随机推荐
- php开发中怎么获取服务端MAC地址?
MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址.硬件地址,用来定义网络设备的位置.在php中如何获取MAC(M ...
- LINUX系统知识(转)
原文链接:http://blog.chinaunix.net/uid-725717-id-2060377.html 在Linux上配置好svnserve,通过eclipse访问,实现版本控制.但是开启 ...
- 知识梳理HTML篇
HTML 浏览器内核: IE:trident Firefox : gecko Safari/chrome : webkit Opera : presto(新 ...
- 前端性能利器——dynatrace ajax edition
因为最近的工作跟性能分析有关系,所以写个小总结. 顺带推荐两个我常用的小工具: 1.文件对比工具beyond compare,非常好用,对比.修改很简单.当然我只是用的试用版本.google一下官网下 ...
- UI第三节—— UITextField详解
戏言:UITextField对于需要登陆注册的界面的作用还是相当明显,但是对于键盘过的遮挡问题,可是重点哦!这里就涉及到通知(NSNotificationCenter)的内容. //注册事件 [[NS ...
- LUXURY15
A - Guess Your Way Out! Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- Request.ServerVariables 参数大全
Request.ServerVariables("Url") 返回服务器地址 Request.ServerVariables("Path_Info") 客户端提 ...
- bootstrap实现弹出窗口
bootstrap使用modal-dialog实现弹对话框. 一个对话框包含3部分: 对话框头部 modal-header 对话框内容体 modal-body 对话框底部 modal-footer 如 ...
- JavaScript与DOM
文档对象模型Document Object Model DOM(Document Object Model,文档对象模型)是一个通过和JavaScript进行内容交互的API.Javascript和D ...
- 关于JavaScript中的创建对象的学习总结
一.最简单的对象创建方法 在JavaScript中,直接使用Object构造函数或对象字面量都可以很轻易地创建单个对象,缺点是:创建具有同一个接口(标准的OO中的接口概念)的多个对象时,会有大量重复代 ...