为什么 UIKit 操作必须在主线程上执行? [英] Why must UIKit operations be performed on the main thread?

查看:20
本文介绍了为什么 UIKit 操作必须在主线程上执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解为什么不能使用多个线程执行 UI 操作.这也是其他框架(如 OpenGL 或 cocos2d)的要求吗?

I am trying to understand why UI operations can't be performed using multiple threads. Is this also a requirement in other frameworks like OpenGL or cocos2d?

C# 和 javascript 等其他语言怎么样?我尝试在 google 中查找,但人们提到了一些我不理解的关于 POSIX 线程的内容.

How about other languages like C# and javascript? I tried looking in google but people mention something about POSIX threads which I don't understand.

推荐答案

在 Cocoa Touch 中,UIApplication 即你的应用程序的实例被附加到主线程,因为这个线程是由 UIApplicatioMain(),Cocoa Touch的入口函数.它设置主事件循环,包括应用程序的运行循环,并开始处理事件.应用程序的主事件循环接收所有 UI 事件,即触摸、手势等.

In Cocoa Touch, the UIApplication i.e. the instance of your application is attached to the main thread because this thread is created by UIApplicatioMain(), the entry point function of Cocoa Touch. It sets up main event loop, including the application’s run loop, and begins processing events. Application's main event loop receives all the UI events i.e. touch, gestures etc.

来自文档<代码>UIApplicationMain(),

此函数从主体类实例化应用程序对象并从给定类实例化委托(如果有)并为应用程序设置委托.它还设置主事件循环,包括应用程序的运行循环,并开始处理事件.如果应用程序的 Info.plist 文件指定要加载的主 nib 文件,则通过包含 NSMainNibFile 键和值的有效 nib 文件名,此函数会加载该 nib 文件.

This function instantiates the application object from the principal class and instantiates the delegate (if any) from the given class and sets the delegate for the application. It also sets up the main event loop, including the application’s run loop, and begins processing events. If the application’s Info.plist file specifies a main nib file to be loaded, by including the NSMainNibFile key and a valid nib file name for the value, this function loads that nib file.

这些应用程序 UI 事件被进一步转发到 UIResponder 跟随响应者链,通常像 UIApplication->UIWindow->UIViewController->UIView->子视图(UIButton等)

These application UI events are further forwarded to UIResponder's following the chain of responders usually like UIApplication->UIWindow->UIViewController->UIView->subviews(UIButton,etc.)

响应者处理按钮按下、点击、捏缩放、滑动等事件,这些事件被翻译为 UI 中的更改.因此,正如您所见,这些事件链发生在主线程上,这就是 UIKit 的原因,包含响应者的框架应该在主线程上运行.

Responders handle events like button press, tap, pinch zoom, swipe etc. which get translated as change in the UI. Hence as you can see these chain of events occur on main thread which is why UIKit, the framework which contains the responders should operate on main thread.

再次从文档 UIKit

From docs again UIKit,

在大多数情况下,UIKit 类只能在应用程序的主线程中使用.对于从 UIResponder 派生的类或涉及以任何方式操作应用程序的用户界面的类尤其如此.

For the most part, UIKit classes should be used only from an application’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your application’s user interface in any way.

编辑

为什么 drawRect 需要在主线程上?

drawRect: 作为 UIView 生命周期的一部分被 UIKit 调用.所以 drawRect: 绑定到主线程.以这种方式绘制很昂贵,因为它是使用主线程上的 CPU 完成的.硬件加速图形是通过使用 CALayer 技术(核心动画)提供的.

drawRect: is called by UIKit as part of UIView's lifecycle. So drawRect: is bound to main thread. Drawing in this way is expensive because it is done using the CPU on the main thread. The hardware accelerate graphics is provided by using the CALayer technique (Core Animation).

CALayer 充当视图的后备存储.然后视图将只显示其当前状态的缓存位图.对视图属性的任何更改都将导致由 GPU 在备份副本上执行的后备存储发生更改.但是,视图仍然需要提供初始内容并定期更新视图.我还没有真正研究过 OpenGL,但我认为它也使用了图层(我可能是错的).

CALayer on the other hand acts as a backing store for the view. The view will then just display cached bitmap of its current state. Any change to the view properties will result in changes in the backing store which get performed by GPU on the backed copy. However, the view still needs to provide the initial content and periodically update view. I have not really worked on OpenGL but I think it also uses layers(I could be wrong).

我已尽我所能回答这个问题.希望对您有所帮助!

I have tried to answer this to the best of my knowledge. Hope that helps!

这篇关于为什么 UIKit 操作必须在主线程上执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆