【问题标题】:GCD Implementation not working with PARSE Query (Swift)GCD 实现不适用于 PARSE Query (Swift)
【发布时间】:2015-06-12 04:48:43
【问题描述】:



我已经查看了 Stack Overflow 和其他网络资源,了解如何处理异步 PARSE 查询并将这些数据存储到数组中。然后我使用这个数组在另一个视图控制器中填充一个表。代码结构如下:

AppController.swift:

public var BuisnessNames = [NSString]()
[...]
public func updateFeedsMap(){

    var query : PFQuery = PFUser.query()!
    var objects : [AnyObject]?
    var counter = 0

    query.whereKey("isProprietor", equalTo: true)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
            if error == nil {
                // The find succeeded.
                println("Successfully retrieved \(objects!.count) scores.")
                // Do something with the found objects
                if let objects = objects as? [PFObject] {
                    for object in objects {
                        dispatch_sync(dispatch_get_main_queue()) {
                            self.BuisnessNames.append(object ["BusinessName"] as! NSString)
                        }
                    }
                }
            } else {
                // Log details of the failure
                println("Error: \(error!) \(error!.userInfo!)")
            }
        }
    }
}

RootVC.swift(从 AppController 继承):

override func viewDidLoad() {
    if isUserLoggedIn() {
        dispatch_async(dispatch_get_main_queue()){
            self.updateFeedsMap()
        }
    }

RootVC 连接到 ViewDidAppear() 中的第三个视图控制器,它使用 BuisnessNames 数组填充表视图。但是,我目前没有将任何数据传递到表格中。我花了很多时间在这上面,我没有想法,请帮忙!谢谢。

【问题讨论】:

    标签: ios swift asynchronous parse-platform grand-central-dispatch


    【解决方案1】:

    您的错误是您在viewDidLoad 中请求数据,该过程是异步的。它会先返回。

    然后你在ViewDidAppear()触发了一个segue,但是此时你还没有从服务器收到任何数据。所以,你的tableview总是空的。

    解决方案:

    收到数据时进行回调。然后对数据做任何你想做的事情

    一个简单的回调演示

    public func updateFeedsMap(completion:()->()){
    
        var query : PFQuery = PFUser.query()!
        var objects : [AnyObject]?
        var counter = 0
    
        query.whereKey("isProprietor", equalTo: true)
        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]?, error: NSError?) -> Void in
    
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                if error == nil {
                    // The find succeeded.
                    println("Successfully retrieved \(objects!.count) scores.")
                    // Do something with the found objects
                    if let objects = objects as? [PFObject] {
                        for object in objects {
                            dispatch_sync(dispatch_get_main_queue()) {
                                self.BuisnessNames.append(object ["BusinessName"] as! NSString)
                            }
                        }
                        //Here your data prase is done
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        completion()
                    })
                    }
                } else {
                    // Log details of the failure
                    println("Error: \(error!) \(error!.userInfo!)")
                }
            }
        }
    }
    

    然后,你像这样调用函数

     self.updateFeedsMap { () -> () in
            //Here do something with data,reloadTableview or whatever you like
        }
    

    【讨论】:

    • 我尝试了各种 GDC 控件并将代码的不同部分包装在异步/同步调度中。我什至尝试过对调度进行分组并使用完成回调……还不能解决这个问题。你能建议你怎么做吗?
    • Leo,很好的解释。但是,使用dispatch_apply 来迭代并在不同的线程上运行以实现并发是否更有意义?还是 BusinessNames 仅在主线程上是线程安全的?
    【解决方案2】:

    不需要您添加的 GCD 代码。 findObjectsInBackground 为您完成 GCD 工作,并调用 main 上的完成块,这是您想要的位置。

    您可以删除调度(在viewDidLoad 和查找完成块中)。只需填写表格的数据源数组并将表格告诉reloadData。请记住以下其他 table view 的陷阱,例如忘记连接数据源和委托,或者忘记在填充之前初始化数组。

    【讨论】:

    • 感谢danh的回复,我按照你的建议做了(删除了GDC)并在第三个VC的viewDidLoad中添加了一个reloadData。依然没有!我确信表格视图的问题得到了解决,因为我可以将初始“测试”值添加到数组中,并且它们可以很好地填充到表格视图中。
    • 好的。让我们开始记录东西。在完成块中,记录对象以查看查询得到了什么。记录您的表视图和应该 == self 的表视图数据源。记录 businessNames 数组。
    • 嗨,danh,我重新编写了代码并添加了一个按钮以在 Parse 查询完成后强制重新加载 tableView。此调试测试有效!我想我现在需要使用正确类型的 GDC 来等待 businessNames 数组在加载表之前填充。
    • 很高兴听到这个消息。但不需要任何 gcd 代码。只需执行查询,然后在完成块中,初始化您的数组并重新加载数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多