FB/Swift: 如何在 FBSDKGraphRequest 中通过 for 循环追加数组?

FB/Swift: How to append an array via a for-loop in FBSDKGraphRequest?

在下面的代码中,我无法通过异步调用中的 for 循环将值附加到数组。我在 graphRequest 之外声明 numbersArray 数组,这样我就可以尝试将 for 循环内的值附加到它并在请求外访问它。问题是,因为 graphRequest 是一个异步调用,它在打印 "numbersArray: \(numbersArray")".

之前打印 "Boston: \(numbersArray)")

"numbersArray: \(numbersArray")" 在每个循环后打印数组的值,而 "Boston: \(numbersArray)") 打印一个空数组,因为它在 graphRequest 之前被调用。我如何访问 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:我无法让观察者在这段代码中只打印一次。我已经移动了 arrayDidChanges 并且没有成功。如果我将 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 命令已执行的数据。解决您的问题的最佳解决方案之一是为结果添加观察者,以便在它发生时通知您。将观察者添加到数组可能有点小技巧,我想为您保持简单,所以我建议您创建一个布尔变量,告诉您值何时完成更改。为此,您需要像这样创建变量

var arrayDidChange:Bool = false {
    didSet{
        if arrayDidChange{
            callFuncDataReadArrayHere()
        }
    } 
}

现在,每次更改数组中的值(添加或编辑)时,都将 arrayDidChange 设置为 true,在阅读并完成所有需要做的事情后,将 arrayDidChange 设置为 false。

这样您将始终确保在填充数组后访问数组中的值。

希望对你有所帮助!