后台子线程(非主线程)更新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的时候,由于要涉及到子线程与主线程传递消息,所以便琢磨了一下.顺便把有用的记录下来,方便自己以后查询及各位同仁的參考! 特此声明,本篇博文主要讲述有用的,也就是直接说明怎么实现,就 ...
随机推荐
- Memcached存储命令 - add
Memcached add 命令用于将 value(数据值) 存储在指定的 key(键) 中. 如果 add 的 key 已经存在,则不会更新数据,之前的值将仍然保持相同,并且您将获得响应 NOT_S ...
- JS禁止WEB页面鼠标事件大全
<!--禁止鼠标右键代码-->:<noscript><ifra:<scriptlanguage=javas:<!--:if(window.Event):doc ...
- Javascript 中我很想说说的 this
this是每一个想要深入学习Javascript的人必过的一关,我为this看过很多书查过很多资料,虽然对this有了一定的了解并且也经常使用this,但是如果有人问我 this是什么呀? 我依旧不 ...
- ios如何普安短图片类型
很多时候需要知道服务器返回的图片是.png还是.jpg或者是.git, 两种方式 1,获取扩展名 //图片 NSString *image = @"4351141241.GIT&quo ...
- Java并发包源码学习之AQS框架(二)CLH lock queue和自旋锁
上一篇文章提到AQS是基于CLH lock queue,那么什么是CLH lock queue,说复杂很复杂说简单也简单, 所谓大道至简: CLH lock queue其实就是一个FIFO的队列,队列 ...
- Java并发包源码学习之AQS框架(一)概述
AQS其实就是java.util.concurrent.locks.AbstractQueuedSynchronizer这个类. 阅读Java的并发包源码你会发现这个类是整个java.util.con ...
- jquery选择器(二)-层次选择器
1. 后代选择器 2. 子元素选择器 3. 相邻兄弟元素选择器 4. 一般兄弟元素选择器(同辈元素选择器) 5. 补充(除自身以外的前后同辈选择器)
- Visual Studio 各种版本的快捷键总结
下列快捷组合键可在工具和文档窗口中用于进行移动.关闭或导航. 命令名 快捷键 说明 视图.全屏 SHIFT + ALT + ENTER 在打开和关闭之间切换“全屏”模式. 视图.向后定位 CTRL + ...
- JQuery在asp.net中三种ajax传值
1)通过webservice,注意去掉注释[System.Web.Script.Services.ScriptService]这行前的注释 2)通过aspx.cs文件中的静态方法 3)通过aspx文件 ...
- springMVC之国际化
1.工程结构 2.jar包 3.配置文件spring-config.xml,springMVC配置文件 <?xml version="1.0" encoding=" ...