Dispatch.main.async如何“更新UI"? [英] How does Dispatch.main.async "update the UI"?

查看:99
本文介绍了Dispatch.main.async如何“更新UI"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Swift已有一段时间了,GCD仍然让我有些困惑.

I've been using Swift for a little while and GCD still confuses me a bit.

我读过:

https://www.raywenderlich.com /60749/grand-central-dispatch-in-depth-part-1

以及派遣的Apple文档:

As well as the Apple docs on dispatch:

https://developer.apple.com/documentation/dispatch

我了解GCD允许多个任务在不同线程上运行的总体概念(我认为是正确的).

I understand the overall concept that GCD allows multiple tasks to be run on different threads (I think that's right).

我不太了解的是Dispatch.main.async如何更新UI".

What I don't quite understand is how Dispatch.main.async "updates the UI".

例如,如果我在某个地方调用api并返回了数据-假设需要5秒钟返回所有数据,那么使用Dispatch.main.async如何帮助更新UI? Dispatch.main.async如何知道要更新的UI?

For example if I make a call to an api somewhere and data is returned - say it takes 5 seconds to return all the data, then how does using Dispatch.main.async help with updating the UI? How does Dispatch.main.async know what UI to update?

我仍然不太了解GCD的位置,为什么相反,当加载所有数据时为什么不能使用某种观察者或委托或闭包来调用?

And i still don't quite get the place of GCD and why instead can't some kind of observer or a delegate or a closure be used that is called when all the data is loaded?

然后重新:如果我正在进行api调用但未立即使用数据,则使用GCD更新UI",例如.只是将数据存储在数组中,直到我决定使用它为止,那么是否需要使用Dispatch.main.async?

And re: "updating the UI" with GCD if I'm making an api call but not using the data immediately eg. just storing the data in an array until I decide to use it is there then any need to use Dispatch.main.async?

我已经将Firebase/firestore用作数据库已有一段时间了. Firebase拥有自己的侦听器并异步运行.我仍然无法得到一个很好的答案:在iOS/Swift中处理Firebase异步返回的最佳方法.例如,当我的应用加载时,如果我去Firebase获取数据以填充tableviewcontroller,那么什么时候才知道所有数据已返回的最佳方法是什么?我一直在为此使用委托,但想知道是否以及如何使用Dispatch.main.async.

And I've been using firebase/firestore as a db for a little while now. Firebase has it's own listeners and runs asynchronously. I still can't get a great answer re: the best way to handle the asynchronous return from firebase in iOS/Swift. For example when my app loads if I go to firebase to get data to populate a tableviewcontroller what is the best way to know when all the data has returned? I've been using a delegate for this but was wondering if and how Dispatch.main.async might be used.

推荐答案

仅供参考,所有UI代码都需要在主线程上运行的原因是,绘图是一个(相对于CPU时间而言)耗时长且昂贵的过程,涉及许多数据结构和数百万个像素.图形代码本质上需要在进行框架更新时锁定所有UI资源的副本,因此您不能在绘制过程中对其进行编辑,否则,如果您在进行过程中进行了一半的更改并进行了更改,则可能会产生一些杂物.系统正在渲染这些对象.由于所有绘图代码都在主线程上,因此这可以让系统阻止main直到完成渲染,因此在完成当前帧之前,您的任何更改都不会得到处理.另外,由于某些图片会被缓存(基本上会渲染为纹理,直到您调用诸如setNeedsDisplay或setNeedsLayout之类的东西),如果您尝试从后台线程更新某些内容,则完全有可能它不会显示并导致状态不一致,这就是为什么您不应该在后台线程上调用任何UI代码的原因.

FYI the reason that all of the UI code needs to go on the main thread is because drawing is a (relatively in CPU time) long and expensive process involving many data structures and millions of pixels. The graphics code essentially needs to lock a copy of all of the UI resources when its doing a frame update, so you cannot edit these in the middle of a draw, otherwise you would have wierd artifacts if you went and changed things half way through when the system is rendering those objects. Since all the drawing code is on the main thread, this lets he system block main until its done rendering, so none of your changes get processed until the current frame is done. Also since some of the drawing is cached (basically rendered to texture until you call something like setNeedsDisplay or setNeedsLayout) if you try to update something from a background thread its entirely possible that it just won't show up and will lead to inconsistent state, which is why you aren't supposed to call any UI code on the background threads.

这篇关于Dispatch.main.async如何“更新UI"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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