有关子线程对UI的线程更新的说法

在 iOS开发过程中,我一直知道更新UI需要在主线程中,但也没怎么细想为什么要在主线程中,或者说为什么不能在子线程中更新UI。

像UIKit这样大的框架上确保线程安全是一个重大的任务,会带来巨大的成本。UIKit不是线程安全的,假如在两个线程中设置了同一张背景图片,很有可能就会由于背景图片被释放两次,使得程序崩溃。或者某一个线程中遍历找寻某个subView,然而在另一个线程中删除了该subView,那么就会造成错乱。apple有对大部分的绘图方法和诸如UIColor等类改写成线程安全可用,可还是建议将UI操作保证在主线程中。

事实上在子线程中如果要对其他UI 进行更新,必须等到该子线程运行结束,而对响应用户点击的Button的UI更新则是及时的,不管他是在主线程还是在子线程中做的更新,意义都不大了,因为子线程中对所有其他ui更新都要等到该子线程生命周期结束才进行。

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

如果在子线程更新UI可能会出现:可能会出现闪退,也可能会引发动画异常,比如整体的动画效果全部消失 包括pop push

结论:

1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新

2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义

说起线程 就不得不提起NSThread类NSOperationQueue和GCD

所以我们可以通过开子线程的方法来提高程序的运行速度,基本我们创建子线程的方法大致分为三种:.......

时间: 2024-08-01 10:45:46

有关子线程对UI的线程更新的说法的相关文章

handler更新UI主线程

示例:下面代码的功能是修改UI主线程TextView的内容 public class MainActivity extends Activity { private Button btn_start; private TextView numTxtView; int i = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContent

Android ActivityThread(主线程或UI线程)简介

1. ActivityThread功能 它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IApplicationThread接口,AMS为Client.ActivityThread.ApplicationThread为Server)负责调度和执行activities.broadcasts和其它操作. 在Android系统中,在默认情况下,一个应用程序内的各个组件(如Activity.BroadcastReceiver.Service)都会在同一个

Android -- ViewRoot,关于子线程刷新UI

Android在4.0之后执行线程更新UI操作会报异常:CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.那么你肯定能看到很多文章说android里子线程不能刷新UI.这句话不能说错,只是有些不太严谨.其实线程能否刷新UI的关键在于ViewRoot是否属于该线程. 首先,CalledFromWrongThreadException这个异

Android - UI线程和异步(AsyncTask)线程

UI线程和异步(AsyncTask)线程 本文地址: http://blog.csdn.net/caroline_wendy Android的UI线程,也称作单线程,单线程应用串行运行所有命令,每个调用都是阻塞的. ANR(Application Not Responding)对话框,当应用程序一定时间(通常是5秒)无响应时,Android系统将会提示终止它. 主UI在前台运行,额外的UI(如联网)在后台运行:可以使用AsyncTask类,执行多线程. AsyncTask类主要有三个操作: do

理解SynchronizationContext,如何在Winform里面跨线程访问UI控件

SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型还简化了托管应用程序为在不同的同步环境下正常工作而必须遵循的一些要求.同步模型的提供程序可以扩展此类并为这些方法提供自己的实现.(来自MSDN)简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线

从setTimeout到浏览器线程机制 ,实现JS线程和UI同时执行的效果

遇到一个问题情况: ocx读取多条记录的结果集. 在js里用 for遍历. for(var i= 0;i<length;i++){ $.ajax({ 后台返回结果 处理成功, 调用更新进度条的方法. }) } 发现,总是当for全部遍历完成,才去渲染进度条控件.更改样式. 查阅N多资料更改后, 将for改为递归调用,没执行一次,渲染一次进度条,后面的JS代码放在setTimeout(function,0),这时浏览器会优先渲染UI界面,然后在执行后面的JS代码,就实现了进度条实时更新了. //更

小知识 安卓线程和ui

1. 定时更新ui 通常需要一些类似定时更新ui的代码,如动画控制. 1.1多线程定时更改ui 具体就是新启动(不让ui线程sleep而卡住)一个线程去计时,之后定时来通知ui修改. 1.1.1新启动线程定时执行任务 Timer + TimerTask 新启动线程:run方法中:while(true) + Thread.Sleep/SystemClock.Sleep 本质上都是一个新线程在背后计时.由于使用一个新的非ui线程执行计时,需要在时间到达后去通知ui修改.出于性能考虑,安卓的ui控件不

Android中子线程和UI线程之间通信的方式

Android中子线程和UI线程之间通信的详细解释 1.在多线程编程这块,我们经常要使用Handler,Thread和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢?下面详解一下. 2.首先在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行. 3.Handler: (1).概念: Handler是沟通Activity 与Thread/runnable的桥梁.而Handler是运行在主UI线程中的,它与子线程

线程操纵UI问题

WPF只允许UI线程修改UI,其他线程必须通过Invoke.委托(安全性)Winform可以开启/关闭"只允许UI线程修改UI" 在WPF中非UI线程修改UI的方法 非UI线程直接修改UI,会报错 System.InvalidOperationException:"调用线程无法访问此对象,因为另一个线程拥有该对象." 正确的做法是 Task t = new Task(() => { NameLabel.Dispatcher.Invoke(new Action(