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 に答える