0

我无法理解为什么每次使用 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,而且确实如此。但为什么?

4

1 回答 1

3

编译器仍然存在各种问题Any,因此简短的回答是“Swift 中的错误”。value如果是协议,它也有问题。我怀疑它无法弄清楚如何制作副本;但这是一个猜测。

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

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

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

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

var items = [OptionToSelect<Int>]()

但这通常是正确的。如果不是;如果您需要混合值,那么您应该考虑所有值可能符合什么协议。这实际上并不能解决您的问题(Swift 也会在此处的协议上崩溃),但设计会比Any. 如果你能说的最好的类型是“好吧,它是某种东西”,你会得到很多复杂的(有时是危险的)向下转换代码。每次转身都会与之抗争。

要在此处(或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)
]

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

于 2014-09-10T16:39:45.317 回答