gpt4 book ai didi

swift - 异步回调中的 Inout 参数未按预期工作

转载 作者:行者123 更新时间:2023-11-30 13:01:30 25 4
gpt4 key购买 nike

我正在尝试插入带有 inout 参数的函数,将从异步回调接收到的数据附加到外部数组。然而,它不起作用。我尝试了我所知道的一切来找出原因 - 但没有成功。

根据@AirspeedVelocity的建议,我重写了代码,如下所示,以删除不必要的依赖项。我还使用 Int 作为 inout 参数以保持简单。
输出始终为:
之前的c:0
c 之后: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 async-callback 中的参数没有意义。

来自the official document :

Parameters can provide default values to simplify function calls and can be passed as in-out parameters, which modify a passed variable once the function has completed its execution.

...

An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.

从语义上讲,输入输出参数不是 "call-by-reference" ,但是"call-by-copy-restore" .

就您而言,counter仅当 getOneUserApiData() 时才回写返回,不在 dataTaskWithRequest() 中回调。

这是您的代码中发生的情况

  1. 位于getOneUserApiData()调用,值counter 0复制到c <子>1
  2. 关闭捕获c <子>1
  3. 调用 dataTaskWithRequest()
  4. getOneUserApiData返回,并且值 - 未修改 - c 1 回写到 counter
  5. c 重复 1-4 过程<子>2 c <子>3 c 4 ...
  6. ...从互联网获取...
  7. 回调被调用并且 c 1 递增。
  8. 回调被调用并且 c 2 递增。
  9. 回调被调用并且 c 3 递增。
  10. 回调被调用并且 c 4 递增。
  11. ...

结果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 ifoo() 时被释放返回。如果x是对 i 的引用, x++导致访问冲突。为了防止这种竞争情况,Swift 在这里采用了“call-by-copy-restore”策略。

关于swift - 异步回调中的 Inout 参数未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39862462/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com