等待在调度异步操作的函数中返回(Swift + Parse)

时间:2015-07-21 16:39:31

标签: ios multithreading swift parse-platform

这是执行异步块的一个基本问题,我还没有找到一个好的解决方案。

以下代码有效,但它会阻止主线程,我想避免这种情况。

override func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool {
    //check if transaction already exists
    let trans = PFQuery(className: "Transactions")
    trans.whereKey("itemId", equalTo: self.pfObject.objectId!)

   //I need the count of objects in the query before I can proceed, but I don't want to block the main thread
   let count = trans.countObjects()
   if(count > 0){
        return false
    }else{
        return true
    }
}

此问题并非特定于我的应用程序的这一部分。通常,我可以在query.countObjectsInBackGroundWithBlock()之类的闭包中设置“count”(或者我需要的任何变量),但是当我需要在主线程上返回一些东西时我不能这样做。

是否有解决方案让我的应用程序等待返回而不阻塞主线程?我实际上并不认为在这种情况下没有重新设计大部分代码,但我只是想确保我不是天真的。

对于这些类型的问题,有哪些可接受的解决方案?

2 个答案:

答案 0 :(得分:5)

对此的正确解决方案是不要从shouldPerformSegueWithIdentifier调用任何不能很快完成的任何内容(在几毫秒内)。如果您需要执行一些可能需要几秒钟的网络请求,您应该:

  • 退休shouldPerformSegueWithIdentifier;

  • 从您的UI控件中移除segue到下一个场景;

  • 相反,将按钮连接到@IBAction,它将以编程方式执行异步请求,并且只有在获得预期结果时,才能以编程方式手动执行segue(请参阅Switching Views Programmatically in Swift

答案 1 :(得分:0)

编辑:这基本上是Rob的更多角色的答案

罗布的答案非常好。另一种方法,如果这是不好的做法,请告诉我,是调用self.performSegueWithIdentifier(我希望我的方法名称正确,来自countObjectsInBackgroundWithBlock的完成块(或者,正如danh指出的那样,Parse阻止计数)查询,使用其他东西,也许是findObjectsInBackgroundWithBlock并计算[AnyObject]?数组。)

//IBAction method
func buttonFunc() { 
    let query = PFQuery(classname: "ClassName")
    query.whereKey(itemId, equalTo: self.pfObject.objectId!)
    query.findObjectsInBackgroundWithBlock {
    (objects: [AnyObject]?, error: NSError?) -> Void in 
        //maybe do some error checking etc.
        if objects.count > 1 {
        performSegueWithIdentifier(theParametersAndStuff)
        }
    }

}

如果需要将对象传递给下一个ViewController,则可以准备ForSegue,因为只有在buttonFunc的完成块中的条件返回true时才会调用它。

(正如我所说,如果有人认为这是不好的做法,请告诉我为什么,我是古玩:))

编辑:当然你可以放一个活动指标或类似的。另一种方法是在显示当前viewController之前预先加载该数据,以启用或禁用触发segue的按钮(如danh指出的那样)。