分配数组属性总是会导致EXC_BAD_ACCESS崩溃

时间:2014-09-10 15:57:25

标签: ios swift exc-bad-access xcode6 xcode6gm

我无法理解为什么每次使用Swift在Xcode 6 GM上崩溃时都会跟踪代码。你能帮我理解这个问题吗?

提前谢谢。

OptionsToSelect.swift

import Foundation

struct OptionToSelect {
    var value : Any
    var desc : String
    var available : Bool
}

SomeClass.swift

import Foundation

class SomeClass {
    var items = Array<OptionToSelect>()
}

ViewController.swift

    override func viewDidLoad() {
        super.viewDidLoad()
        var c = SomeClass()
        c.items = [ /// <------------- __ EXC_BAD_ACCESS here, why?! __
            OptionToSelect(value: 1, desc: "A", available: true),
            OptionToSelect(value: 2, desc: "B", available: true)
        ]
    }

修改1 在Twitter上,我得到了答案,它与Any有关,的确如此。但为什么呢?

1 个答案:

答案 0 :(得分:3)

编译器仍然存在Any的各种问题,因此简短的回答是#34; Swift中的错误。&#34;如果value是协议,也会遇到麻烦。我怀疑它无法弄清楚如何制作副本;但这是猜测。

但你应该强烈避免在这里使用Any。你几乎不应该使用Any。在大多数情况下,您需要通用:

struct OptionToSelect<T> {
  let value : T
  let desc : String
  let available : Bool
}

(您使用它的方式,let似乎比var更合适;您真的需要更改这些值吗?)

这确实要求整个数组具有相同类型的值:

var items = [OptionToSelect<Int>]()

但无论如何,这通常都是正确的。如果它不是;如果您需要混合值,那么您应该考虑所有值可能符合的协议。这实际上并没有解决你的问题(Swift也会在协议上崩溃),但设计会比Any好得多。如果关于类型的最好的话就是&#34;嗯,它是什么,&#34;你会得到很多复杂的(有时是危险的)下传代码。你每次转身就会对抗它。

要在此处使用协议(或Any),您可以将OptionToSelect作为一个类(这是最简单的答案),或者在框中隐藏问题:

struct OptionToSelect {
  let value : AnyBox
  let desc : String
  let available : Bool
}

final class AnyBox {
  let value: Any
  init (_ value: Any) { self.value = value }
}

[
  OptionToSelect(value: AnyBox(1), desc: "A", available: true),
  OptionToSelect(value: AnyBox(2), desc: "B", available: true)
]

(协议类型需要相同的技术。)