如何修复附加函数的异步性质?

时间:2016-12-16 17:23:29

标签: swift multithreading grand-central-dispatch parse-server

我设置了一个查询来从数据库中提取数据(由heroku托管的Parse-server)并将其附加到数组中;在此查询中是另一个查询,用于从另一个类提取信息,但也用于追加另一个数组。我认为因为我使用 func getQueries(completion: (() -> Void)?){ let searchQuery = PFQuery(className: "Etc") searchQuery.findObjectsInBackground(block: { (objects, error) in if let objectss = objects{ for object in objectss { //append some arrays let otherQuery = PFQuery(className: "OtherClass") otherQuery.whereKey("user", equalTo: object["User"] as String) otherQuery.findObjectsInBackground(block: {(objects, error) in if let objectss = objects{ for object in objectss{ array.append(object["ProfPic"] as PFFile) print("\(array) and its count is \(array.count)") //this returns a non 0 value } } completion!() }) print("\(array) and its count is \(array.count)") //this returns 0 } } }) } 它会异步发生,这会导致问题。这是代码(概括):

array

searchQuery的计数一旦被附加在自己的闭包中,就会返回为非0,但在其闭包之外返回为0。这是一个问题,因为数组用于迭代显示信息。无论如何要确保在完成otherQuery的整体关闭之前,{{1}}的追加已经完成了吗? (另外,它是异步发生导致问题的事实是猜测......我可能是错的)

1 个答案:

答案 0 :(得分:1)

在后一种情况下,您正在打印提取数据的计数,例如,在findObjectsInBackground的完成区之外。

您可以使用完成块将整个事物包装在自己的方法中:

func fetchData(_ completion: () -> Void) {

    searchQuery.findObjectsInBackground(block: { (objects, error) in
        guard let objectss = objects else {
            completion() 
        }

        for object in objectss {
            let otherQuery = PFQuery(className: "OtherClass")
            otherQuery.whereKey("user", equalTo: object["User"] as String)
            otherQuery.findObjectsInBackground(block: {(objects, error) in

                guard let objectss = objects else {
                    completion()
                }

                for object in objectss{
                    array.append(object["ProfPic"] as PFFile)
                }

                print("In loop: \(array) and its count is \(array.count)")                
                completion()
            })
        }
    })
}

而不是像这样:

fetchData() {
     print("After completing: \(array) and its count is \(array.count)")
    // do stuff with your fetched data and display it
    // "use in iterating through to display information" here
}

更新

在您更新的问题中,您仅在成功案例中呼叫completion!()。你必须在任何情况下都打电话给它:

...
if let objectss = objects 
    ...
    completion!()
} else {
    completion!()
} 
...