我正在尝试插入带有inout
参数的函数,以将从异步回调接收的数据追加到外部数组。但是,它不起作用。我尽一切所能找出原因-没运气。
正如@AirspeedVelocity所建议的那样,我将代码重写如下,以删除不必要的依赖项。我还使用an Int
作为inout
参数来保持简单。
输出始终为:
c before: 0
c after: 1
我无法弄清楚这里出了什么问题。
func getUsers() {
let u = ["bane", "LiweiZ", "rdtsc", "ssivark", "sparkzilla", "Wogef"]
var a = UserData()
a.userIds = u
a.dataProcessor()
}
struct UserData {
var userIds = [String]()
var counter = 0
mutating func dataProcessor() -> () {
println("counter: \(counter)")
for uId in userIds {
getOneUserApiData(uriBase + "user/" + uId + ".json", &counter)
}
}
}
func getOneUserApiData(path: String, inout c: Int) {
var req = NSURLRequest(URL: NSURL(string: path)!)
var config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
var session = NSURLSession(configuration: config)
var task = session.dataTaskWithRequest(req) {
(data: NSData!, res: NSURLResponse!, err: NSError!) in
println("c before: \(c)")
c++++
println("c after: \(c)")
println("thread on: \(NSThread.currentThread())")
}
task.resume()
}
谢谢。
可悲的是,修改inout
在异步回调参数是没有意义的。
从官方文件:
参数可以提供默认值以简化函数调用,并且可以作为输入-输出参数传递,参数 在函数完成执行后会 修改传递的变量。
…
输入输出参数具有一个值,该值传递给函数,由函数修改,然后从函数 传递回 以替换原始值。
语义上,输入输出参数不是“按引用调用”,而是“按复制副本恢复”。
就您而言,counter
仅在getOneUserApiData()
返回时才回写,而不在dataTaskWithRequest()
回调中。
这是您的代码中发生的事情
getOneUserApiData()
调用时,将值counter
0
复制到c
1c
1dataTaskWithRequest()
getOneUserApiData
返回,并且-未经修改c
-1的值被写回到counter
c
2,c
3,c
4 …c
1递增。c
2递增。c
3递增。c
4递增。结果counter
是未修改的:(
详细说明
通常,in-out
参数是通过引用传递的,但这只是编译器优化的结果。当闭包捕获inout
参数时,“传递引用”是 不安全的
,因为编译器无法保证原始值的生存期。例如,考虑以下代码:
func foo() -> () -> Void {
var i = 0
return bar(&i)
}
func bar(inout x:Int) -> () -> Void {
return {
x++
return
}
}
let closure = foo()
closure()
在此代码中,返回var i
时foo()
将其释放。如果x
是对的引用i
,x++
则会导致访问冲突。为了防止出现这种竞争情况,Swift在此处采用了“按副本还原呼叫”策略。
问题内容: 建立: 我正在做一个ajax-jsonp调用,它工作正常。此的回调函数更改变量“ myVaraible”的值。在调用之后,有一些if-else逻辑对“ myVaraible”的值起作用。 这是代码: 问题: Ajax调用保持“待处理”状态,控制移至if- else块(有效执行myVariable的旧/陈旧值)。然后,ajax调用完成。简而言之,在两个方框中,先执行然后执行 如您所见,我
在我的flatter应用程序中,我试图在异步函数完成后使用whenComplete()方法运行一些代码。问题是whenComplete()方法中的代码甚至在异步函数完成之前就被执行了。 我也尝试过使用then()方法,这也产生了相同的结果。 这是我在其中调用异步函数的init函数: 这是异步函数的函数体: 运行应用程序时的控制台输出为: 因此,在调用异步函数getUserHomes的init()函
问题内容: 我正在使用selenium来抓取一些数据。 我单击的页面上有一个按钮,说“ custom_cols”。此按钮为我打开一个窗口,从中可以选择列。 此新窗口有时需要一些时间才能打开(大约5秒钟)。所以我已经使用了 延迟为20秒。但是有时它无法在新窗口中选择查找元素,即使该元素可见。在其余时间中,这种情况仅发生十次一次。 我在其他地方也使用了相同的功能(WebDriverWait),并且可以
问题内容: 经过测试后,我只能对已经解析过的JSON数据返回一个肯定值。 根据官方文件: isValidJSONObject返回一个布尔值,该布尔值指示是否可以将给定对象转换为JSON数据。 但是,尽管事实是我尝试将其从JSON转换为NSDictionary的对象都可以正常转换,但仍会返回。 这是我的代码: 我的日志包含以下内容: 然后是dict的输出,这是一个巨大的NSMutableDictio
问题内容: 考虑以下可以在任何程序执行之前预加载的库: 问题是,尽管总是调用全局变量的构造函数,但对于某些程序却不调用析构函数,例如: 对于其他一些程序,按预期方式调用析构函数: 您能解释一下为什么在第一种情况下不调用析构函数吗?编辑:上面的问题已得到解答,即程序可能会使用_exit(),abort()退出。 然而: 有没有办法在预加载的程序退出时强制调用给定函数? 问题答案: 具有作为其初始化代
我必须将日期-时间字符串转换为分区日期-时间对象。我使用DateTimeForman读取模式。根据留档,模式中的“Z”可以接受以下格式: /-0000 但是“分区约会”。parse(myDate,formatter)只适用于第一种情况;相反,在第二种情况下,代码生成一个异常。 我用的是8Java 我做错什么了?谢谢!