[转载]iOS 开发中为什么更新UI都要放在主线程中?

摘要:
无论是在主线程还是在子线程中进行更新,都没有什么意义,因为子线程中的所有其他UI更新都必须等到子线程的生命周期结束。如果子线程一直在运行,则无法知道子线程中用于UI更新的函数堆栈的主线程,即无法更新。2.只能更新少数UI功能,因为打开线程时将获得当前环境。例如,单击按钮将通过打开子线程来响应。子线程中按钮的UI更新是及时的,例如更改标题和背景,但这没有任何意义

原因有2个:

1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新
 
2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义
 

1、程序一开始运行就进入了主线程
 
2、处理某些数据太过费时,影响用户交互,可以开辟子线程处理,然后通知主线程进行界面更新
 
测试代码:
 
开辟一个多线程,直接在子线程里进行ui 更新:
 
-(void)testUIRefresh:(UIButton *)button{

       [NSThread detachNewThreadSelector:@selector(beginTest) toTarget:self withObject:nil];

}
 
-(void)beginTest {
       NSLog(@” 当前线程  %@”,[NSThread currentThread]);

       NSLog(@” 主线程    %@”,[NSThread mainThread]);

      //该button 为  响应 testUIRefresh的button

       [self.button setTitle:@"AAA" forState:0];

}
 

2012-11-15 12:14:02.147 TestProj[2455:1b07]  当前线程  {name = (null), num = 3}
 
2012-11-15 12:14:02.147 TestProj[2455:1b07]  主线程    {name = (null), num = 1}
 
结果:当前的确是在子线程中,但是UI马上更新了??

结果分析:大家都说UI更新在主线程中做,上面的结果怎么解释

假设:如果在子线程里做了UI更新,待子线程运行完毕,程序自动进入 主线程进行指定的ui更新!

问题:如果子线程没结束呢?

在分线程中加入:
-(void)beginTest{
      NSLog(@” 当前线程  %@”,[NSThread currentThread]);

      NSLog(@” 主线程    %@”,[NSThread mainThread]);

      //该button 为  响应 testUIRefresh的button

      [self.button setTitle:@"AAA" forState:0];

      [NSThread sleepForTimeInterval:4.0];

}
 
结果:

self.button的title还是马上更新了

结果分析:难道上面的假设不成立?

问题:这次在分线程中add 一个button

-(void)beginTest{

      NSLog(@” 当前线程  %@”,[NSThread currentThread]);

      NSLog(@” 主线程    %@”,[NSThread mainThread]);

      //该button 为  响应 testUIRefresh的button
      [self.button setTitle:@"AAA" forState:0];
      UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
      [backButton setTitle:@"测试runloop" forState:0];
      [backButton setTitleColor:[UIColor redColor] forState:0];
      backButton.frame = CGRectMake(100, 200, 100, 50);
      [backButton addTarget:self action:@selector(testRunLoop)    forControlEvents:UIControlEventTouchUpInside];
      [self.window addSubview:backButton];
      [NSThread sleepForTimeInterval:4.0];

}
 
结果:[self.button setTitle:@"AAA" forState:0];马上响应了,但是添加的这个Button却一直等到线程结束才绘制出来
 
分析:在子线程中:如果要对其他UI 进行更新,则必须等到该子线程运行结束,而对响应用户点击的Button的UI更新则是及时的!不管他是在主线程还是在子线程中做的更新,意义都不大了,因为子线程中对所有其他ui更新都要等到该子线程生命周期结束才进行。
 
 
 
结论:
 
1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新
 
2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义

免责声明:文章转载自《[转载]iOS 开发中为什么更新UI都要放在主线程中?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇React Native可用的css属性如何快速清除ZBrush画布中多余图像下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Ext.MessageBox.show更改按钮中的名称

  Ext.MessageBox.show({                     title: "提示",                     msg: "您未选择记录,请选择以下操作",                     buttons:{                         "ok":"新增协议",             ...

iOS WKWebView 使用笔记

首先添加Webkit框架 导入#import <WebKit/WebKit.h> #import <WebKit/WebKit.h> @interface WebBrowerViewController ()<WKNavigationDelegate> @property(nonatomic,strong) WK...

github 中删除/更名版本库(repository)

问题描述: github 中版本库创建/删除/更该名称 问题解决:            (1)创建版本库(Repository) 注:        在上图中的+按钮图标指示的是创建版本库的按钮 注:        创建版本库的名称,以及具体属性           (2)重命名版本库 注:        如上图所示,对于已经创建的版本库更名,首...

转:WaitForSingleObject()函数、WaitForMultipleObject()函数

http://blog.csdn.net/xiaobai1593/article/details/6672193 在多线程下面,有时候我们会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects。这两个函数都会等待Object被标为有...

linux下用/proc/stat文件来计算cpu的利用率-c语言实现

proc文件系统介绍       /proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统内核读出所需信息并...

Weex 初始

1.一旦数据和模板绑定,数据的变化会立即体现在前台的变化 <template> <container> <text style="font-size: {{size}}">{{title}}</text> </container> </template> <sc...