Why must UIKit operations be performed on the main thread?(为什么 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 操作必须在主线程上执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 UIKit 操作必须在主线程上执行?
基础教程推荐
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01