Ios 等待函数先执行,然后再移动到下一行代码

Ios 等待函数先执行,然后再移动到下一行代码,ios,swift,uitableview,cloudkit,Ios,Swift,Uitableview,Cloudkit,我在应用程序中使用CloudKit,在表视图中显示数据时遇到问题。在viewDidLoad中,我正在从CloudKit数据库获取数据 然后在表视图函数中,我对行数进行CKRecord对象计数 但count将0返回到表视图,几秒钟后返回行数。由于此原因,表视图不显示结果 override func viewDidLoad() { super.viewDidLoad() loadNewData() } func loadNewData() { self.loadData =

我在应用程序中使用CloudKit,在表视图中显示数据时遇到问题。在viewDidLoad中,我正在从CloudKit数据库获取数据

然后在表视图函数中,我对行数进行CKRecord对象计数

但count将0返回到表视图,几秒钟后返回行数。由于此原因,表视图不显示结果

override func viewDidLoad() {
    super.viewDidLoad()
    loadNewData()
}

func loadNewData() {
    self.loadData = [CKRecord]()
    let publicData = CKContainer.default().publicCloudDatabase
    let qry = CKQuery(recordType: "Transactions", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
    qry.sortDescriptors = [NSSortDescriptor(key: "Transaction_ID", ascending: true)]
    publicData.perform(qry, inZoneWith: nil) { (results, error) in
        if let rcds = results {
            self.loadData = rcds
        }
        if error != nil {
            self.showAlert(msg: (error?.localizedDescription)!)
        }
    }
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return loadData.count
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell2", for: indexPath) as! ViewAllTransactionsTVCell

    let pn = loadData[indexPath.row].value(forKey: "Party_Name") as! String
    let amt = loadData[indexPath.row].value(forKey: "Amount") as! String
    let nrt = loadData[indexPath.row].value(forKey: "Narattions") as! String 
    let dt = loadData[indexPath.row].value(forKey: "Trans_Date") as! String


    cell.partyNameLabel.text = pn
    cell.dateLabel.text = dt
    cell.narationLabel.text = nrt
    cell.amountLabel.text = amt

    return cell
}

您不应该等待,而是在调用执行完成处理程序时触发重新加载数据:

publicData.perform(qry, inZoneWith: nil) { (results, error) in
    if let rcds = results {
        DispatchQueue.main.async {
            self.loadData = rcds
            self.tableView.reloadData()
        }
    }
    if error != nil {
        self.showAlert(msg: (error?.localizedDescription)!)
    }
}
注意,我将重新加载进程分派到主队列,因为不能保证在主线程上运行该进程。正如上面所说:

你的程序块必须能够在应用程序的任何线程上运行


由于UI更新必须在主线程上进行,并且您希望同步对loadData的访问,因此只需将其发送到主队列,如上所述。

回答您的问题时,不要等待。只需在publicData.perform完成处理程序中调用self.tableView.reloadData。如果你试图等待,你可能会引入各种微妙的问题。顺便说一句,如果你对否决票感到疑惑,毫无疑问,这是因为这个问题在堆栈溢出问题上已经被问了数百次并回答了数百次。只需搜索[ios]wait for function,或者更狭义地搜索[ios]cloudkit wait.hi。谢谢你的回复。最后,它调用tableview函数。但现在我得到了致命的错误:在展开可选值错误时意外地发现了nil。尝试了每一件事,但没有luckWell,您必须确定是哪一行导致了错误,不是吗。不过,loadData是一个可能的候选人。你是怎么定义的?如果是可选的,则numberOfRowsInSection应返回loadData?count??0,即如果可以安全地展开,则返回0。如果在解包可选项时没有从中获取找到的nil,请告诉我们哪一行生成了该错误。错误来自tableView…第2行fn的单元格,我在其中使用了let pn=loadData[indexPath.row]。valueforKey:Party\u Name as!字符串和其他行可能会导致它停止,因为它停止在那里error@Aakash那么,问题是在您成功地从CloudKit返回数据之后?好的,那么loadData实际上包含什么?也许你的密钥名不对。您需要进行一些诊断以找出问题所在。我认为“loadData”返回正确的值,因为它返回实际的行数。对于键-Party_Name是字符串,Trans_Date是字符串,Amount是Double,narations是字符串,我不知道是什么导致了错误。