在闭包中使用数组时Swift EXC_BAD_ACCESS

在闭包中使用数组时Swift EXC_BAD_ACCESS,第1张

概述考虑以下玩具示例 Swift代码: protocol Testable{}class MyObj : Testable{}class Test { var arr:[Testable] = [] var didRun:Bool = false func run() -> [Testable]{ if(didRun){ pri @H_502_6@ 考虑以下玩具示例 Swift代码:

protocol Testable{}class MyObj : Testable{}class Test {    var arr:[Testable] = []    var dIDRun:Bool = false    func run() -> [Testable]{        if(dIDRun){            println("arr has \(arr.count) elements")            for e in arr{  // following access causes EXC_BAD_ACCESS                println(e)            }            return arr        } else{            provIDer({ (myArr : [AnyObject]) -> () in                self.arr = myArr as [MyObj]                self.dIDRun = true                })            return []        }    }    func provIDer( cb : ([AnyObject] -> ()) ){        let a:[MyObj] = [MyObj(),MyObj(),MyObj()]        cb(a)    }}

并按以下方式调用它:

let t = test() t.run() t.run()

这会在尝试迭代返回的数组时编译但在运行时崩溃. arr.count也是垃圾,返回一个随机的大数字,如232521760和arr本身指向远在0xfffffff9附近的某个地方,这意味着它显然是垃圾.

我的问题是为什么会这样?编译器不会抱怨类型错误.为什么我无法使用myArr数组,编译器在离开闭包后是否取消分配myArr?

我可以通过将提供者调用更改为:

provIDer({ (myArr : [AnyObject]) -> () in    for e in myArr{      self.arr.append(e as MyObj)    }    self.dIDRun = true })

但我更感兴趣的是为什么我的第一个代码不起作用.

如果有人可以向我解释Swift中的闭包语义以及为什么上面会产生这样的错误,我将不胜感激.

解决方法 编辑:正如 @SevenTenEleven(苹果员工) ADF thread related to this question所述:

It looks like there are issues with some covariant array assignments; please file a BUG so we can either properly ban them at compile-time or properly implement them at runtime.

我们这样做,I did.

做了一些experiments和research后,我得出以下结论:

>这与clousures和外部范围无关
>只有将[AnyObject]向下转换为[MyObj]时才会发生错误
>只有将“外部”变量声明为协议类型数组时,错误才会出现

由于似乎提供者总是返回Testable,因此我能够通过更改提供者函数声明并将变量显式标记为Testable数组来使代码工作:

func provIDer(cb: [Testable] -> ()) {    let a : [Testable] = [MyObj(),MyObj()]    cb(a)}

然后没有必要垂头丧气,所以没有错误.这是整个代码:

protocol Testable {}class MyObj : Testable {}class Test {    var arr : [Testable] = []    var dIDRun = false    func run() -> [Testable] {        if dIDRun {            println("arr has \(arr.count) elements")            for e in arr {                println(e)            }            return arr        } else {            provIDer() { (myArr : [Testable]) in                self.arr = myArr                self.dIDRun = true            }            return []        }    }    func provIDer(cb: [Testable] -> ()) {        let a : [Testable] = [MyObj(),MyObj()]        cb(a)    }}let t = test()t.run()t.run()

前面的代码输出:

arr has 3 elements_TtC5hgfds5MyObj_TtC5hgfds5MyObj_TtC5hgfds5MyObj
总结

以上是内存溢出为你收集整理的在闭包中使用数组时Swift EXC_BAD_ACCESS全部内容,希望文章能够帮你解决在闭包中使用数组时Swift EXC_BAD_ACCESS所遇到的程序开发问题。

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

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存