博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转载]iOS 开发中为什么更新UI都要放在主线程中?
阅读量:5040 次
发布时间:2019-06-12

本文共 2209 字,大约阅读时间需要 7 分钟。

原因有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(@” 当前线程   currentThread]);

       NSLog(@” 主线程     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(@” 当前线程   currentThread]);

      NSLog(@” 主线程     mainThread]);

      //该button 为  响应 testUIRefresh的button

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

      [NSThread sleepForTimeInterval:4.0];

}

 
结果:

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

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

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

-(void)beginTest{

      NSLog(@” 当前线程   currentThread]);

      NSLog(@” 主线程     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 更新是能及时的,如换标题,换背景图,但这没有任何意义

转载于:https://www.cnblogs.com/congliang/p/3782070.html

你可能感兴趣的文章
日常报错
查看>>
list-style-type -- 定义列表样式
查看>>
hibernate生成表时,有的表可以生成,有的却不可以 2014-03-21 21:28 244人阅读 ...
查看>>
mysql-1045(28000)错误
查看>>
Ubuntu 编译出现 ISO C++ 2011 不支持的解决办法
查看>>
1.jstl c 标签实现判断功能
查看>>
Linux 常用命令——cat, tac, nl, more, less, head, tail, od
查看>>
超详细的Guava RateLimiter限流原理解析
查看>>
VueJS ElementUI el-table 的 formatter 和 scope template 不能同时存在
查看>>
Halcon一日一练:图像拼接技术
查看>>
Swift - RotateView
查看>>
iOS设计模式 - 中介者
查看>>
centos jdk 下载
查看>>
HDU 1028 Ignatius and the Princess III(母函数)
查看>>
关于多路复用器的综合结果
查看>>
(转)面向对象最核心的机制——动态绑定(多态)
查看>>
token简单的使用流程。
查看>>
django创建项目流程
查看>>
UIActionSheet 修改字体颜色
查看>>
Vue 框架-01- 入门篇 图文教程
查看>>