Swift 如何正确使用DispatchQueue.main.async?

Swift 如何正确使用DispatchQueue.main.async?,swift,for-loop,asynchronous,dispatch-queue,Swift,For Loop,Asynchronous,Dispatch Queue,我的应用程序中有一个循环,可能需要几秒钟来处理 当循环在后台运行时,我希望屏幕立即关闭 这可能吗 我尝试只添加循环: DispatchQueue.main.async { for _ in 1...self.numberOfTransactionsToAdd { let newTransaction = Transaction()

我的应用程序中有一个循环,可能需要几秒钟来处理

当循环在后台运行时,我希望屏幕立即关闭

这可能吗

我尝试只添加循环:


DispatchQueue.main.async {
                for _ in 1...self.numberOfTransactionsToAdd {
                    
                    let newTransaction = Transaction()
                    
                    var timeAdded = 1.months
                    newTransaction.transactionAmount = self.amountTextField.text!.toDouble()
                    newTransaction.transactionDescription = self.descriptionTextField.text
                    newTransaction.transactionDate = self.datePicked
                    newTransaction.transactionCategory = self.categoryPicked
                    newTransaction.repeatInterval = self.repeatInterval
                    newTransaction.transactionSubCategory = self.subcategoryPicked
                    newTransaction.subCategoryName = self.subcategoryPicked!.subCategoryName
                    
                  
                    try! self.realm.write {
                        self.realm.add(newTransaction)
                    }
                    
                    self.datePicked = self.datePicked + timeAdded
                }
            }
                
            }

我已尝试添加整个函数:

    @IBAction func doneButtonPressed(_ sender: UIButton) {
        
        self.dismiss(animated: true, completion: nil)

        DispatchQueue.main.async {

            self.saveTransaction()

        }
        
    }
但在视图被取消之前,屏幕仍然挂起

这是我第一次使用DispatchQueue。我读过苹果公司关于它的文档,但它非常模糊

这样做对吗


有人能帮助新手找到正确的方法吗?

看来你的问题在于GCD:

@IBAction func doneButtonPressed(_ sender: UIButton) {
    DispatchQueue.global(qos: .background).async {
//  do here your loading, fetching the data etc
        self.saveTransaction()
    DispatchQueue.main.async {
//  do here ui works, because user doesn't want to wait for touching etc so it has to be asp
        self.dismiss(animated: true, completion: nil)
    }
  }
}

问题是对非ui工作(后台工作)的主队列本身的异步调用。 将
DispatchQueue.main.async
替换为
DispatchQueue.global().async
。原因是所有非ui任务都应该在主队列之外异步运行

在完成上述修复之后,您仍然会遇到另一个问题,即从非主队列访问UI元素(现在我们的代码将在全局队列上运行)。原因是您将从全局队列获取UI元素数据(如amountTextField的文本等)。将UI的数据存储在局部变量中,并在循环代码中使用局部变量,而不是调用amountTextField和其他TextField

var amountData: Double
var description: String

@IBAction func doneButtonPressed(_ sender: UIButton) {
    amountData = amountTextField.text!.toDouble()
    descriptionTextField = descriptionTextField.text
    DispatchQueue.global().async {
        self.saveTransaction()
    }
    self.dismiss(animated: true, completion: nil)
}

func saveTransaction() {
    for _ in 1...self.numberOfTransactionsToAdd {
        .
        .
        newTransaction.transactionAmount = self.amountData
        newTransaction.transactionDescription = self.descriptionTextField
        .
        .
        .
    }
    
}

为什么有两个
调度队列
?代码的第一段是否显示了
saveTransaction
?这些代码片段只是我尝试过的两件不同的事情,而不是放在一起。当我尝试这一点时,我得到了“由于未捕获的异常'RLMException'而终止应用程序”,原因是:“从错误的线程访问的领域”。我没有不尊重的意思,我非常感谢您的帮助。我会调查这个问题,并不断更新这个页面。