[转载]iOS 开发中为什么更新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
更新是能及时的,如换标题,换背景图,但这没有任何意义

时间: 2024-10-05 09:39:40

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

[转载]IOS开发之----strong和weak (IOS5新特性)

iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的. 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都很熟悉了,在此我也不介绍,网上有很多相关文章. 现在我们看看iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained功能差不多(有点区别,等下会介绍,这两个新关键字与a

转载 IOS开发之---static变量

Objective-C 支持全局变量 主要有两种实现方式: (1)第一种和C/C++中的一样, 使用"extern"关键词: (2)另外一种就是使用单例实现. (比如我们经常会把一个变量放在AppDelegate里面作为全局变量来访问, 其中AppDelegate就是一个单例类)  在Objective-C中如何实现像C++中那样的静态成员变量呢? 你需要做的是在一个类A的implementation(.m或者.mm)文件中定义一个static变量,然后为A类定义静态成员函数(clas

[转载]ios 开发 icon图标设置

iTunes Artwork icon ───────────────────────── 512px (90px) App icon(iPhone4) ────────────────────────── 114px (20px) App icon(iPad) ───────────────────────────── 72px (12px) App icon(iPhone 3G/3GS) ───────────────────── 57px(10px) Spotlight/Settings

WPF中异步更新UI元素

XAML 界面很简单,只有一个按钮和一个lable元素,要实现点击button时,lable的内容从0开始自动递增. <Grid> <Label Name="lable_plus" Content="0"/> <Button Content="Button" Click="button_Click" Height="23" Name="button" Wid

WinForm/Silverlight多线程编程中如何更新UI控件的值

单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么做,比如: private void btnSet_Click(object sender, EventArgs e){        Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue));    //当然也可以用匿名委托写成

Android子线程刷新主线程中View

最近遇到一问题,ListView Item加载多个图片,图片是在Adapter的getView方法通过子线程异步进行加载的. 这时候就涉及到子线程刷新主线程中View的问题,一般有两个方式, 1.View.post(Runnable); 2.Activity.runOnUiThread(Runnable); 首次是使用View.post方式来刷新界面,但是一直刷新失败,debug发现图片下载已经成功,View.post方法也已经调用了,但是图片刷新一直没有成功. 很纳闷,于是加上log看了一下,

[转载]iOS开发之手势识别

感觉有必要把iOS开发中的手势识别做一个小小的总结.在上一篇iOS开发之自定义表情键盘(组件封装与自动布局)博客中用到了一个轻击手势,就是在轻击TextView时从表情键盘回到系统键盘,在TextView中的手是用storyboard添加的.下面会先给出如何用storyboard给相应的控件添加手势,然后在用纯代码的方式给我们的控件添加手势,手势的用法比较简单.和button的用法类似,也是目标动作回调,话不多说,切入今天的正题.总共有六种手势识别:轻击手势(TapGestureRecogniz

[转载]IOS开发-正则表达式的使用方法

原文地址:http://www.cnblogs.com/GarveyCalvin/p/4250145.html?utm_source=tuicool&utm_medium=referral 前言:在表单验证中,我们经常会使用到正则,因为我们需要用它来判断用户输入的字符是否为合法的,如果是不合法的,那么应该提示用户输入错误,并不让提交至服务器.我们也可以通过正则表达式,从用户输入的字符串中过滤并获取我们想要的特定部分.总而言之,正则表达式是非常强大的. 方法一.谓词(NSPredicate)创建正

iOS开发 - 第02篇 - UI进阶 - 08 - 私人通讯录

实现:私人通讯录 源代码下载地址: 点击打开链接 1.实现要求 1> 多个控制器之间的跳转 2> 控制器之间的数据传递 3> 数据存储 2.登录界面到联系人列表界面实现思路 2.1 登录界面搭建 1> 在Storyboard中添加导航控制器,设置根控制器,并设置导航条的title 2> 搭建登录界面 注1:设置UITextField占位符和清楚文字按钮 注2:设置密码UITextField的暗文 注3:记住密码UILabel和开关以及自动登录UILabel和开关分别放在一个U