swift – 异步回调中的Inout参数无法按预期工作

swift – 异步回调中的Inout参数无法按预期工作,第1张

概述我正在尝试使用inout参数插入函数,以将从异步回调接收的数据附加到外部数组.但是,它不起作用.我尝试了所知的一切,找出原因 – 没有运气. 正如@AirspeedVelocity建议的那样,我重写了如下代码以删除不必要的依赖项.我还使用Int作为inout参数来保持简单.输出始终是: c之前:0 c之后:1 我无法弄清楚这里出了什么问题. func getUsers() { let u 我正在尝试使用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()}

谢谢.

不幸的是,在async-callback中修改inout参数是没有意义的.

从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”.

在您的情况下,只有当getoneUserAPIData()返回时,计数器才会被写入后备,而不是在dataTaskWithRequest()回调中.

以下是您的代码中发生的情况

>在getoneUserAPIData()调用时,将计数器0的值复制到c1
>闭包捕获c1
>调用dataTaskWithRequest()
> getoneUserAPIData返回,并且 – unmodifIEd – c1的值被写回到计数器
>对c2,c3,c4重复1-4程序……
> …从互联网上取货……
>调用回调并且c1递增.
>调用回调,c2递增.
>调用回调并且c3递增.
>调用回调并且c4递增.
> ……

因此,计数器未经修改:(

详细解释

通常,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()

在此代码中,当foo()返回时,将释放var i.如果x是对i的引用,则x会导致访问冲突.为了防止这种竞争条件,Swift采用了“逐个复制恢复”策略.

总结

以上是内存溢出为你收集整理的swift – 异步回调中的Inout参数无法按预期工作全部内容,希望文章能够帮你解决swift – 异步回调中的Inout参数无法按预期工作所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1033758.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存