一、问题描述

-(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引起的警告的更多相关文章

  1. Android 快速切换到主线程更新UI的几种方法

    此最近看了网上,在子线程更新UI的方法,说法很多,但都不是很全面.在此我争取做到总结的全面一些,希望以后对自己,对大家都有一些帮助. 方法一: view.post(Runnable action) 假 ...

  2. 一定要在主线程更新UI

    在一些技术交流群里面,一些初学者(我表示我也是其中一人),总是会发现,为什么我UIView的animate方法,不会动!而是直接闪? 这是为什么呢? 一定要在主线程中更新UI! 一定要在主线程中更新U ...

  3. 在非主线程中更新UI

    在非主线程中调用了showMessage方法,结果报错:Can't create handler inside thread that has not called Looper.prepare() ...

  4. Android 在非主线程无法操作UI意识

    Android在应用显示Dialog是一个非常easy事儿,但我从来没有尝试过Service里面展示Dialog. 经验UI操作要在主线程,本地的服务Service是主线程里没错,可是远程servic ...

  5. 开子线程下载图片,回到主线程刷新UI步骤

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [NSThread detachN ...

  6. WPF里面多线程访问UI线程、主线程的控件

    如果出现以下错误:调用线程无法访问此对象,因为另一个线程拥有该对象. 你就碰到多线程访问UI线程.主线程的控件的问题了. 先占位.

  7. 在非主线程里面使用NSTimer创建和取消定时任务

    为什么要在非主线程创建NSTimer 将 timer 添加到主线程的Runloop里面本身会增加线程负荷 如果主线程因为某些原因阻塞卡顿了,timer 定时任务触发的时间精度肯定也会受到影响 有些定时 ...

  8. [转]QT子线程与主线程的信号槽通信-亲测可用!

    近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号槽 ...

  9. ThreadLocal ——android消息机制handler在非主线程创建not called Looper.prepare() 错误的原因

    引用自:https://www.jianshu.com/p/a8fa72e708d3 引出: 使用Handler的时候,其必须要跟一个Looper绑定.在UI线程可直接初始化Handler来使用.但是 ...

  10. Qt自己定义事件实现及子线程向主线程传送事件消息

    近期在又一次学习Qt的时候,由于要涉及到子线程与主线程传递消息,所以便琢磨了一下.顺便把有用的记录下来,方便自己以后查询及各位同仁的參考! 特此声明,本篇博文主要讲述有用的,也就是直接说明怎么实现,就 ...

随机推荐

  1. 如何使用UltraCompare对比两个文件夹内容差异

    http://jingyan.baidu.com/article/cb5d6105e13599005c2fe0f8.html  

  2. [译]在Mac上运行ASP.NET 5

    原文:http://stephenwalther.com/archive/2015/02/03/asp-net-5-and-angularjs-part-7-running-on-a-mac 这篇文章 ...

  3. HDU 2007

    /*杭电ACM ID:2007*/ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { int in1, in2 ...

  4. 初探Ajax

    1.什么是Ajax Ajax是Asynchronous JavaScript and XML的缩写,这一技术能从服务器请求额外数据而无需卸载页面.传统的HTTP请求流程大概是这样的,浏览器向服务器发送 ...

  5. 微信小程序即将开放申请?微信小论坛小程序专场16日或可见分晓

    9月22号微信小程序内测至今已经好一段时间了,首批只开放了200个名额,没拿到内测资格的朋友早就等到心急了.就在刚刚,微信公开课宣布微信小论坛小程序专场即将在11月16号举行,微信公众平台小程序会在当 ...

  6. 全文检索引擎Solr系列——整合MySQL、MongoDB

    MySQL 拷贝mysql-connector-java-5.1.25-bin.jar到E:\solr-4.8.0\example\solr-webapp\webapp\WEB-INF\lib目录下面 ...

  7. “北航Clubs”功能规格说明书

    1.项目目标说明: 北航Clubs的初衷是服务社团,服务学生,满足社团与学生的信息互通的需求.社团管理运营方便的需求. 建设网站的目的是使学生可以在一个权威可信的网站上获取到社团实时的动态,社团活动的 ...

  8. W3Cschool菜鸟教程离线版下载链接

    请在电脑上打开以下链接进行下载w3cschool 离线版(chm):http://pan.baidu.com/s/1bniwRCV(最新,2014年10月21日更新)w3cschool 离线版(htm ...

  9. JVM内存模型和关键参数设置

    一. JVM内存模型: Jvm内存模型是学好Java很重要的一部分,该部分学习能让我们在系统运维的时候,或者优化服务器的时候能够有方法,懂原理. 二. Jvm关键参数: 1. 堆大小设置参数: -Xm ...

  10. angularjs的$http.jsonp跨域的用法

    var app = angular.module("app",[]); app.run(function ($rootScope,$http) { $http.jsonp(&quo ...