Ios 移动数据时使用findObjectsInBackgroundWithBlock的最佳方法

Ios 移动数据时使用findObjectsInBackgroundWithBlock的最佳方法,ios,parse-platform,nsnotificationcenter,Ios,Parse Platform,Nsnotificationcenter,我有一个Tableview,它使用viewDidLoad中的findObjectsInBackgroundWithBlock获取数据,并将该数据传递给详图视图控制器,没有问题 我在管理findObjectsInBackgroundWithBlock中的流时遇到问题。下面是一个例子:我在细节视图上有一个like按钮,按下它时,会增加UILabel并显示它。然后,它还会在解析中获取对象,然后递增并保存它。。。一切都好 @IBAction func likeButtonPressed(sender:

我有一个Tableview,它使用viewDidLoad中的findObjectsInBackgroundWithBlock获取数据,并将该数据传递给详图视图控制器,没有问题

我在管理findObjectsInBackgroundWithBlock中的流时遇到问题。下面是一个例子:我在细节视图上有一个like按钮,按下它时,会增加UILabel并显示它。然后,它还会在解析中获取对象,然后递增并保存它。。。一切都好

 @IBAction func likeButtonPressed(sender: AnyObject) {
    print("likeButtonPressed()")
    // Adding the like to label
    mixLike!++
    var stringForCount: String = String(mixLike!)
    mixLikeLabel.text = stringForCount
    // Saving the like back to Parse
    var query = PFQuery(className: "musicMixes")
    query.whereKey("info", equalTo: mixNameLabel.text)
    query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!, error:NSError!) -> Void in
        if error == nil {
            for object in objects {
                //var votes = object["votes"] as! Int
                let mixObject:PFObject = object as! PFObject
                mixObject.incrementKey("votes", byAmount: 1)
                mixObject.saveInBackgroundWithTarget(nil, selector: nil)
              print("mixObjectSaved")
            }

        } else {
            print("Error getLikeCount()")
        }
        print("sending Notification...")
        NSNotificationCenter.defaultCenter().postNotificationName("reload", object: nil)
        print("sent Notification...")

    }

} // likeButtonPressed End
然后,我还将NSNotification回调到表视图,以便表视图可以更新likes以匹配用户,如单击详细信息视图,请参见下文 NSNotification在表视图中调用此函数,删除like数组,再次获取新like,然后重新加载表视图

@ objc func reloadTableData(notification: NSNotification){
    print("Notification Recived, Removing Likes and Reloading. reloadTableData()...")
    self.mixLikeArray.removeAll()
    //self.stringForCountArray.removeAll()
    print("Like array Data removed, getting data again...")
    var query = PFQuery(className: "musicMixes")
    query.orderByAscending("date")
    query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!,error: NSError!) -> Void in
        if error == nil {
            for object in objects {
                let mixLike = object["votes"] as! Int
                self.mixLikeArray.append(mixLike)
                print("New mixLikeArray data is \(self.mixLikeArray)")

            }
        } else {
            print("error getting like object")
        }
    }

    dispatch_async(dispatch_get_main_queue(),{
        self.allTableView.reloadData()
    });

}
我认为目前的工作方式存在三个问题。likeButtonPressed有时在mixObject.saveInBackgroundWithTarget完成之前发送NSNotification。这意味着递增的like不会显示在表视图上

其次,如果我要单击“喜欢”,然后单击“返回到tableview”,应用程序将崩溃。这是因为我猜likeButtonPressed和NSNotification功能都还没有完成

同样在@objc func reloadTableDatanotification:NSNotification中

dispatch_async(dispatch_get_main_queue(),{
    self.allTableView.reloadData()
});
是否在findObjectsInBackgroundWithBlock完成之前调用?不管怎样,围绕着这个


你会建议我如何改造它以有效地工作?我对编码很陌生,对设计最好的方法有些生疏。。。我知道完成处理程序背后的概念我可以使用这些吗?我知道Parse喜欢在后台工作,尽管hhmmmm…

要解决您的reloadTableData问题,您应该在Parse块执行完毕后触发reload,这意味着移动此行

 dispatch_async(dispatch_get_main_queue(),{
    self.allTableView.reloadData()
});
街区内

 query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]!,error: NSError!) -> Void in
    if error == nil {
        for object in objects {
            let mixLike = object["votes"] as! Int
            self.mixLikeArray.append(mixLike)
            print("New mixLikeArray data is \(self.mixLikeArray)")

        }
        dispatch_async(dispatch_get_main_queue(),{
            self.allTableView.reloadData()
        });
    } else {
        print("error getting like object")
    }
}
这将确保在完成更新对象的解析后触发它。当前,当块正在执行时,它将在此之前触发。这还意味着,如果您遇到错误,它将不会重新加载,因为您可能需要以不同的方式处理该错误

至于在保存完成之前发生的通知问题,您正在致电。saveInBackgroundWithTarget,但似乎没有向其中发送任何内容。您可以使用saveinbackgroundithblock,然后在块内使用dispatch\u group dispatch\u group\u enter、dispatch\u group\u leave和dispatch\u group\u notify,以使程序在发送通知之前等待保存完成所有操作

因此,您将创建一个dispatch_组

 dispatch_group_t group = dispatch_group_create();
然后将其称为dispatch\u group\u,并通过对象进入for循环

 for object in objects {
     dispatch_group_enter(group);
     let mixObject:PFObject = object as! PFObject
     .....
 }
然后在mixObject.saveinbackgroundithblock上调用dispatch\u group\u leave

并将通知包装在dispatch\u group\u notify中

  dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 4
      NSNotificationCenter.defaultCenter().postNotificationName("reload", object: nil)
});
诸如此类


这听起来比实际情况更让人望而生畏,如果您不熟悉,这里有一个教程可以让您了解如何使用它。

谢谢您提供的信息!!向块剂量工作添加重新加载数据。但是,当在循环中使用解析块时,它会在每次追加后重新加载数据。我想看看是否有办法避免这种情况,只在迭代结束时追加。我将研究这篇文章,似乎GCD是解决这个问题的方法。更重要的是,如果在保存对象和完成通知之前返回表视图,如何阻止应用程序崩溃。必须有一种方法来重塑我的代码,以避免this@user4671001抱歉,我承认我不熟悉parse的工作原理,所以不确定我是否能在这方面帮助您。如果问题是您试图在更新完成之前重新加载,那么dispatch_group和dispatch_group_notify肯定会对您有所帮助