无法在函数内更新数组

时间:2016-02-01 03:32:12

标签: ios arrays swift variables

嘿我正在使用Swift 2,我正在尝试创建一个方法,该方法返回通过查询从数据库下载的ID字符串数组。我的问题是在函数内我无法更新我的数组,这意味着我可以从服务器访问下载的信息,但由于某种原因我不能将它附加到我的数组。或者更好,我可以,但它并没有真正做任何事情。我的阵列似乎保持空洞。

func ATMsAroundMe(myLocation : PFGeoPoint) -> [String]{
    var results = [String]()
    let query = PFQuery(className: "ATMs")
    query.whereKey("location", nearGeoPoint: myLocation, withinMiles: 5)
    query.limit = 10
    query.findObjectsInBackgroundWithBlock { (atms: [PFObject]?, error: NSError?) -> Void in
        if (error == nil) {
            for atm in atms! {
                print(atm.objectId) //Works!
                results.append(atm.objectId!) //Doesn't work
            }

        } else {
            // Log details of the failure
        }
    }
    print(results) //Prints "[]"
return results
}

所以是的,如果你对我做错了什么有任何建议或任何想法,那么如果你能告诉我,那将非常有帮助和赞赏。 感谢。

2 个答案:

答案 0 :(得分:0)

这里的问题是电话 -

query.findObjectsInBackgroundWithBlock

这是一个异步调用,因此,您的方法只是返回,因为它不等待此异步调用返回的结果。因此,您需要考虑表单中的异步API ATMsAroundMe -

func ATMsAroundMe(myLocation : PFGeoPoint, completionHandler:(Bool,[String]?) ->Void){

    let query = PFQuery(className: "ATMs")
    query.whereKey("location", nearGeoPoint: myLocation, withinMiles: 5)
    query.limit = 10
    query.findObjectsInBackgroundWithBlock { (atms: [PFObject]?, error: NSError?) -> Void in
        if (error == nil) {
            for atm in atms! {
                print(atm.objectId) //Works!
                var results = [String]()
                results.append(atm.objectId!)
                completionHandler(true, results)
            }

        } else {
            // Report the failure
            completionHandler(false, nil)
        }
    }

}

您现在可以将此API称为 -

ATMsAroundMe(myLocation){(success :Bool, results:[String]?) in
 if(success){
       if let results = results {
       //Process results
    }
}
}

同步解决方案

func ATMsAroundMe(myLocation : PFGeoPoint) -> [String]{
    var results = [String]()
    let query = PFQuery(className: "ATMs")
    query.whereKey("location", nearGeoPoint: myLocation, withinMiles: 5)
    query.limit = 10
    //Declare a semaphore to help us wait until the background task is completed.
    let sem = dispatch_semaphore_create(0);
    query.findObjectsInBackgroundWithBlock { (atms: [PFObject]?, error: NSError?) -> Void in
        if (error == nil) {
            for atm in atms! {
                print(atm.objectId) //Works!
                results.append(atm.objectId!) 
                 dispatch_semaphore_signal(sem);
            }

        } else {
            // Log details of the failure
              dispatch_semaphore_signal(sem);
        }
    }
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    print(results) //Should print your results

return results
}

注意在主线程中调用此同步API时要小心,它可能会停止主线程,直到调用返回,就像任何其他同步调用一样。

答案 1 :(得分:0)

结果未更新的原因是因为它在另一个块范围内更新。因此更新的值仅在该块范围内持久存在。要获得更新的结果,您需要在Objective-c中的变量声明中使用闭包或__block。 这里很好地解释了here in BLOCKS VS CLOSURES