在Swift 3.0中从异步线程调用UIAlertController

Adr*_*ian 2 asynchronous grand-central-dispatch ios swift swift3

我有一个IBAction调用函数,该函数有时会显示来自异步线程的错误警报。它在模拟器中“有效”,但出现此错误:

CoreAnimation:警告,已删除的线程具有未提交的CATransaction; 在环境中设置CA_DEBUG_TRANSACTIONS = 1以记录回溯。

看到该错误后,我意识到我正在尝试从主线程更新UI,并且需要对其进行修复。

这是我正在调用的异步函数:

let queue = DispatchQueue(label: "com.adrianbindc.myApp.myFunction")

queue.async {
    self.createArray()

    switch self.arrayIsEmpty() {
    case true:
        // TODO: update on the main thread
        self.displayAlert(alertTitle: "Error Title", alertMessage: "Error Message")
    case false:

        // Do Stuff Off the Main Queue
        DispatchQueue.main.async{
            switch someArray.count {
            case 0:
                // TODO: update on the main thread
                self.displayAlert(alertTitle: "Another Error Title", alertMessage: "Another error message.")
            default:
                // Do other stuff
            }
        }       
    }
}

/**
 Utility method to display a single alert with an OK button.
 */
func displayAlert(alertTitle: String, alertMessage: String) {
    let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
    let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
    alertController.addAction(okAction)
    self.present(alertController, animated: false, completion: nil)
}
Run Code Online (Sandbox Code Playgroud)

我尝试过的

我尝试@objc在我的displayAlert函数前添加并在async块中调用如下警报函数:

self.performSelector(onMainThread: #selector(ViewController.displayAlert(alertTitle: "Error Title", alertMessage: "Error Message")), with: self, waitUntilDone: false)
Run Code Online (Sandbox Code Playgroud)

但我在编译器中收到此错误:

在类型“ ViewController”上使用实例成员“ displayAlert”;您的意思是改用'ViewController'类型的值吗?

任何建议有关:非常感谢我的错误所在。感谢您的阅读。

Adr*_*ian 6

我走在正确的道路上,但是我使用的语法不正确(通常)。当我调用alert函数时,这会在主线程上执行操作,这意味着我需要获取主线程。

这是我在异步块中调用警报的方式:

// ** This gets the main queue **
DispatchQueue.main.async(execute: {
    self.displayAlert(alertTitle: "Another Error Title", alertMessage: "Another error message.")
}
Run Code Online (Sandbox Code Playgroud)

这是成品的外观:

let queue = DispatchQueue(label: "com.adrianbindc.myApp.myFunction")

queue.async {
    self.createArray()

    switch self.arrayIsEmpty() {
    case true:
        // ** This gets the main queue **
        DispatchQueue.main.async(execute: {
            self.displayAlert(alertTitle: "Error Title", alertMessage: "error message.")
        })

    case false:
        switch resultArray.count {
        case 0:
            // ** This gets the main queue **
            DispatchQueue.main.async(execute: {
                self.displayAlert(alertTitle: "Another Error Title", alertMessage: "Another error message.")
            })
        default:
            // Do other stuff
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这个答案使我越过终点,并拥有更多场景,其中一些场景可能对Swift 3.0有所帮助。