I cannot understand why following code every time crashes on Xcode 6 GM using Swift. Could you help me to understand this issue?
Thank you in advance.
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)
]
}
Edit 1
On twitter I got answer that it's related to Any
, and indeed. But why?
The compiler still has various problems with
Any
, so the short answer is "bug in Swift." It also has trouble ifvalue
is a protocol. I suspect that it has trouble figuring out how to make a copy; but that's a guess.But you should strongly avoid using
Any
here. You almost never should useAny
. In most cases, you want a generic:(The way you're using it,
let
seems more appropriate thanvar
here; do you really need to change these values?)This does require that the entire array have the same kinds of values:
But that's usually correct anyway. If it isn't; if you need a mix of values, then you should consider what protocol all the values might conform to. That won't actually solve your problem (Swift will crash on a protocol here too), but the design will be much better than
Any
. If the best you can say about the type is "well, it's something," you're going to get a lot of complicated (and sometimes dangerous) down-casting code. You'll fight it every time you turn around.To use a protocol here (or
Any
) you can either makeOptionToSelect
a class (which is the easiest answer), or hide the problem in a box:(The same technique is needed for protocol types.)