当dispatch_async完成执行代码时,屏幕不会更新

时间:2016-06-22 22:27:20

标签: ios

我在IOS 9自定义键盘应用扩展程序中有以下代码用于删除按钮:

func deletekeyPressed(sender: UIButton!) {

    NSLog("-------------------")
    NSLog("Pressing delete key")

    sender.setTitle("Deleting...", forState: .Normal)
    sender.userInteractionEnabled = false



    dispatch_async(dispatch_get_main_queue()) {
    NSLog("Starting delete function")

        while(self.textDocumentProxy.hasText()) {
         //   NSLog("Deleting 3 times")
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
        }

        for _ in 1..<2000 {
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
        }

        sender.setTitle("Clear", forState: .Normal)
        sender.userInteractionEnabled = true

        NSLog("Finishing delete function")
    }

}

代码应该执行以下操作:当按下删除键时,其文本将从&#34; Clear&#34;切换。到&#34;删除...&#34;直到所有文本都完成删除。这是为了防止用户认为键盘正在崩溃,同时删除文本。

问题是解决方案只能部分工作。删除密钥的文本确实更改为&#34;正在删除...&#34;直到dispatch_async内的代码完成,然后它确实恢复为默认删除按钮文本&#34;清除&#34;。问题是Iphone的屏幕没有显示在功能完成调用后立即删除文本。

这导致删除按钮的文本切换回&#34;清除&#34;在文本实际显示为已删除之前。我不知道为什么在异步任务完成执行后屏幕的其余部分不会更新(只有按钮的文本更新)。

以下是展示问题的视频:

bdemo

为什么在异步任务完成时屏幕没有更新(除了删除按钮)?

2 个答案:

答案 0 :(得分:0)

从您的代码中,我看到您正在使用主线程进行一些CPU密集型工作,因此无法更新UI。 (没有我自己的转载)。

问题部分似乎是这样的:

  

dispatch_async(的 dispatch_get_main_queue()

您应该在后台线程中进行CPU密集型工作,并在完成后继续主线程。

也许尝试这样可能有所帮助:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

        NSLog("Starting delete function")

        while(self.textDocumentProxy.hasText()) {
         //   NSLog("Deleting 3 times")
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
        }

        for _ in 1..<2000 {
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
        }

    // Wait to complete async work and continue the UI update in main thread
    dispatch_sync(dispatch_get_main_queue(), ^{
        // update some UI

        sender.setTitle("Clear", forState: .Normal)
        sender.userInteractionEnabled = true

        NSLog("Finishing delete function")
    });
});

答案 1 :(得分:0)

您的代码运行速度太快,无法观察任何内容。如果你想直观地观察删除,你应该把你运行的代码放在NSTimer方法中,该方法每0.1秒触发一次。