代码只能在DispatchQueue.main.async块中运行,为什么? [英] Code only works within a DispatchQueue.main.async block, why?

查看:704
本文介绍了代码只能在DispatchQueue.main.async块中运行,为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写此代码以在用户开始编辑UITextField时选择所有文本:

I wrote this code to select all the text when a user begins editing a UITextField:

@IBAction func onEditingBegin(_ sender: Any) {
    print("editing began")
    let textfield = sender as! UITextField
    textfield.selectAll(nil)
}

但它不会工作直到我在 DispatchQueue.main.async 块中附上 textfield.selectAll(nil)行:

But it wouldn't work until I enclosed the textfield.selectAll(nil) line in a DispatchQueue.main.async block:

DispatchQueue.main.async {
    textfield.selectAll(nil)
}

为什么?

我还打印出了线程的名称 onEditingBegin(),结果如下:

I also printed out the name of the thread in onEditingBegin() and this was the result:

< NSThread:0x60800006c880> { number = 1,name = main}

所以它似乎已经在主线程上被激活,但代码仍然没有除非 DispatchQueue.main.async 块内调用textfield.selectAll()

So it seems that it is already being fired on the main thread, but the code is still not working unless textfield.selectAll() is called inside of the DispatchQueue.main.async block.

推荐答案

调用 DispatchQueue.main.async 的真正效果是添加一个小小的,微小延迟。特别是,这种延迟足够长,足以让当前的runloop完成并启动下一个runloop。因此,允许完成,导致事件被发送给您的操作(调用 onEditingBegin )。现在的文本字段是编辑,因此我们准备好进行下一步,即选择其内容。

The real effect of your call to DispatchQueue.main.async is to add a tiny, tiny delay. This delay, in particular, is exactly long enough to allow the current runloop to finish and the next runloop to start. The action that has caused an event to be sent to you, calling onEditingBegin, is thus permitted to complete. The text field now is editing, and so we are ready for the next step, namely to select its contents.

你的伎俩发现实际上是iOS编程中经常需要的东西。 Cocoa是一个复杂的框架,界面的操作有时可能会绊倒彼此的脚,就像这里一样 - 当用户开始在文本字段中编辑时,您正试图选择文本字段的文本。有时我们只需要再次运行runloop,以便在继续下一步之前允许界面安定下来。

The trick you've discovered is actually something that is surprisingly often needed in iOS programming. Cocoa is a complicated framework, and manipulations of the interface sometimes can stumble over one another's feet, as here — while the user is starting to edit in the text field, you are trying to select the text field's text. Sometimes we just need the runloop to come around one more time in order to permit the interface to "settle down" before proceeding to the next step.

这篇关于代码只能在DispatchQueue.main.async块中运行,为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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