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,打印第一行的最后一行,添加第二行,打印第二行的最后一行,依此类推。您可以在表视图中添加新行并在其读取时设置动画,并在结尾处具有完整的表视图一次保存一行没有问题,在这种情况下实际上更好,只需在后台线程中保存,将比批量下载和保存所有行更快信任我