我对此的第一遍是JavaScript代码示例,它看起来应该可以工作,但仔细检查就会发现行为不同。我的Swift代码目前带有SwiftyJSON:
for(var index = 0; index < datesToLoad.count; index += 1) {
var formattedDate = formatter.stringFromDate(datesToLoad[index]);
if (presentLocation["days"][formattedDate] == nil) {
loadDataFromURL(NSURL:"http://api.sunrise-sunset.org/json?formatted=0&lat=\(presentLocation.coordinate.latitude)&lon=\(presentLocation.coordinate.longitude)&date=\(formattedDate)&formatted=0", completion: {(data, error) -> Void in {
if (var json = JSON(data:data)) {
presentLocation["days"][formattedDate]["sunrise"] = parser(json["results"]["sunrise"]);
presentLocation["days"][formattedDate]["sunset"] = parser(json["results"]["sunset"]);
}
}
}
}
现在,我希望代码不会按预期运行。我要完成的工作是,对于列表的每个formattedDate值,都会进行一个异步调用以从URL检索数据,并且每个API调用都将与进行
formattedDate
调用时仍处于 Activity 状态的loadDataFromURL()
值一起使用。我预期将发生的是,循环将快速运行,并生成一些异步请求,并且formattedDate
将使用定义的最后一个值。我可能可以解决不知道如何在Swift中正确执行此操作的问题,因为从API返回的数据会给出多个时间戳,但是我想知道通过回调函数查看formattedDate
的多个值的首选方式,在调用其loadDataFromURL()
函数时处于 Activity 状态。我还可以通过完全展开(四个元素)循环并为每个基于闭包的API调用使用单独的变量名称来获得所需的结果,但是我真的更想知道处理这种问题的正确方法是什么。
最佳答案
每次通过for
循环都会创建一个新的formattedDate
变量,该变量与在其他任何遍次上创建的formattedDate
变量无关。
因此,您的循环应该可以实现您的预期。
游乐场演示:
import XCPlayground
import UIKit
var blocks: [()->Void] = []
for i in 0..<5 {
var s = "\(i)"
blocks.append( { print(s) } )
}
print("calling blocks")
for block in blocks {
block()
}
输出:
calling blocks
0
1
2
3
4