代码只能在DispatchQueue.main.async块中运行,为什么?

时间:2017-01-18 01:32:01

标签: ios swift

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

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

但是只有在textfield.selectAll(nil)块中包含DispatchQueue.main.async行后才能生效:

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

为什么?

我还在onEditingBegin()中打印出了帖子的名称,这就是结果:

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

所以它似乎已经在主线程上被触发了,但是除非在textfield.selectAll()块内部调用DispatchQueue.main.async,否则代码仍然无效。

1 个答案:

答案 0 :(得分:5)

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

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