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所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)