Facebook FB/Swift:如何通过FBSDKGraphRequest中的for循环附加数组?

Facebook FB/Swift:如何通过FBSDKGraphRequest中的for循环附加数组?,facebook,swift,facebook-graph-api,for-loop,Facebook,Swift,Facebook Graph Api,For Loop,在下面的代码中,我在异步调用中通过for循环向数组追加值时遇到问题。我在graphRequest外部声明numbersArray数组,以便尝试将for循环内部的值附加到它,并在请求外部访问它。问题是,因为graphRequest是一个异步调用,所以它在打印“numbersArray:\(numbersArray”)“之前打印 “numbersArray:\(numbersArray”)”在每个循环后打印数组的值,而“Boston:\(numbersArray)”打印空数组,因为它是在graphR

在下面的代码中,我在异步调用中通过
for
循环向数组追加值时遇到问题。我在
graphRequest
外部声明
numbersArray
数组,以便尝试将
for
循环内部的值附加到它,并在请求外部访问它。问题是,因为
graphRequest
是一个异步调用,所以它在打印
“numbersArray:\(numbersArray”)“
之前打印

“numbersArray:\(numbersArray”)”
在每个循环后打印数组的值,而
“Boston:\(numbersArray)”
打印空数组,因为它是在
graphRequest之前调用的。如何使用
图形请求
外部的
值访问
数字阵列

class Test {

    class func test() {

        var numbersArray = [String]()

        let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me/", parameters: nil)
        graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

            var array = ["1", "2", "3"]

            for number in array {
                numbersArray.append(number)
            }

            println("numbersArray: \(numbersArray)")

        })

        println("Boston: \(numbersArray)")

    }
}  

更新:下面是我如何编辑代码的

class Test {

        class func test() {

            var numbersArray = [String]()

            var arrayDidChange:Bool = false {
                didSet {
                   if arrayDidChange {
                     println("Boston: \(numbersArray)")
                   }
                }
            }

            let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me/", parameters: nil)
            graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

                var array = ["1", "2", "3"]

                for number in array {
                    numbersArray.append(number)
                    arrayDidChange = true
                }


            })

            arrayDidChange = false

        }
    }

更新#2:我无法让观察者在这段代码中只打印一次。我已将
arrayDidChange
s四处移动,但没有成功。如果我将
arrayDidChange=true
语句移出
for
循环,则
songArray
为空

class Test {

    class func test() {

        var songArray = [String]()
        var testArray = ["Trap Queen", "Dream Lover", "All Of Me"]

        var arrayDidChange: Int = 0 {
            didSet {
               if arrayDidChange == 0 {
                   println("Boston: \(songArray)")
               }
            }
        }

        arrayDidChange++

        let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me/music.listens", parameters: nil)
        graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

            if let data = result["data"] as? NSArray {

                for songs in data {

                    if let songData = songs["data"] as? NSDictionary {

                        if let song = songData["song"] as? NSDictionary {

                            if let id = song["id"] as? String {

                                let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "\(id)", parameters: nil)
                                graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

                                    if let title = result["title"] as? String {

                                        if contains (testArray, title) {

                                            songArray.append(title)

                                            arrayDidChange--
                                        }
                                    }
                                })
                            }
                        }
                    }
                }
            }
        })
    }
}

FBSDKGraphRequest是异步的,因此当程序仍在主线程中运行时,它将在后台线程中发生,此时后台线程将返回println命令已执行的数据。解决问题的最佳方法之一是为结果添加观察者,以便在结果发生时通知您。将观察者添加到数组可能是一个小技巧,我想让它对您保持简单,因此我建议您创建一个布尔变量,当值finish更改时,它会告诉您。为此,您需要像这样创建变量

var arrayDidChange:Bool = false {
    didSet{
        if arrayDidChange{
            callFuncDataReadArrayHere()
        }
    } 
}
现在,每次更改数组中的值(添加或编辑)时,您都会将ArrayIDChange设置为true,然后在阅读并执行所有需要执行的操作后,将ArrayIDChange设置为false

通过这种方式,您将始终确保在填充数组后访问数组中的值


我希望这对你有帮助

我对
callFuncDataReadArrayHere()
的含义有点困惑。您介意澄清一下在该调用中要做什么吗?该调用将在您获得数据后对数组执行任何您想执行的操作,在这个特定示例中,您只需将其发布到println(“Boston:(numbersArray)”)中即可,请参阅上面的更新代码。我的问题是,
“Boston\(numbersArray)”
打印三次,每个循环一次,即使它在
循环和
graphRequest的
之外。有没有办法让它只打印一次,还是总是打印
array.count
次?你需要在完成添加或编辑数组后添加arrayDidChange=true,只需将它移到循环之外,因为它在我的项目中不起作用,但在我给你的代码中起作用。因此,我接受你的回答!明亮的只需要弄清楚为什么它现在在我自己的项目中不起作用。您在for循环中添加了异步块,这会有点复杂,您需要创建一个计数器,而不是一个布尔值,在调用startWithCompletionHandler之前增加它,然后从块内部减少它。在didSet中,当值为零时,您将打印。然而,通过这种方式,你的应用程序最终将更新所有异步调用的建议,也许这将使它仍然是异步的,并解决你的问题,在println(“Boston:(numbersArray)”)中,将其更改为println(“Boston:(numbersArray.last)”)所以它将像以前一样打印,但只是新的条目。@IcaroNZ-Hmm我不能使用
numbersArray.last
,因为我只需要检索一次完全附加的数组。我在尝试你的第一个建议,但它只是打印了第一个值。我是否正确使用了您的方法?使用numbersArray.last并不意味着您将只使用最后一行,它意味着您添加的每一行都将读取新行,例如,如果您添加3行,它将首先添加1,打印第一行的最后一行,添加第二行,打印第二行的最后一行,依此类推。您可以在表视图中添加新行并在其读取时设置动画,并在结尾处具有完整的表视图一次保存一行没有问题,在这种情况下实际上更好,只需在后台线程中保存,将比批量下载和保存所有行更快信任我