一、问题描述

-(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. Windows下设置自动关机命令

    选择“开始→运行”:1.输入“at 22:00 Shutdown -s”,这样,到了22点电脑就会出现“系统关机”对话框,默认有30秒钟的倒计时并提示你保存工作.2.输入 “Shutdown.exe ...

  2. C语言中的EOF和回车不一样

    经常我们碰到这样一个C语言问题,例如: 输入一个组整数,按照从小到大排序后输出结果 输入:  1 7 9 2 4 输出:  1 2 4 7 9 这里要用C语言读入一段数的话,如果用 int array ...

  3. caller和callee

    我们先来看下caller. caller:返回一个对函数(该函数调用了当前函数)的引用. functionName.caller:functionName对象是所执行函数的名称. 说明 对于函数来说, ...

  4. js做灯泡明灭特效

    W3school中的js专讲这一块 http://www.w3school.com.cn/tiy/t.asp?f=js_lightbulb

  5. MySQL事物控制

    有时候我们需要保证事物的各个步骤都执行成功的前提下才能让每一步骤的事物执行,此时就需要事物控制. 事物控制用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败 ...

  6. Java中将unix时间戳转化为正常显示时间

    在unix中时间戳是一串数字表示的,使用起来非常不方便,转化方式如下: //Convert Unix timestamp to normal date style public String Time ...

  7. button事件驱动

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. Inno Step 安装包程序 写INI配置文件脚本

    [INI]Filename: "{app}\Config\config.ini"; Section: "config";Key: "name" ...

  9. RFM

    前面博客中讲到的聚类,聚类是对客户的一些特征进行分群,属于描述,不涉及客户价值的判断,然而在营销中,其实第一步应该是搞清楚谁才是你的关键客户,哪些用户的价值较高,这就需要用到RFM模型.RFM模型是众 ...

  10. Fedora 24最新工作站版本之四大重要改进

    导读 2014年,Fedora.next倡议正式开始建立Fedora Linux未来十年的发展规划.从本质上讲,这项规划旨在进一步使Fedora不再只是一套汇聚多种开源产品的通用库(例如Debian) ...