0

次のSwiftコードを使用してSwiftクラスを解凍しています:

 required convenience init(coder decoder: NSCoder) {
    self.init()

    horseID = decoder.decodeIntegerForKey("horseID")
    name    = decoder.decodeObjectForKey("name") as String!

    // if the thumb key does not exist, the following line crashes
    thumb   = decoder.decodeObjectForKey("thumb") as UIImage!
}

「親指」クラスのメンバーは後で追加されました。サム データが含まれていない古いアーカイブ ファイルがあります。Apple のドキュメントによると、存在しないキーのアーカイブを解除すると nil が返されます。これは、おなじみの Objective-C の動作です。Swift コードがエラー コード EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) でクラッシュします。

から に変更しても問題は解決asas?ません。

これにより、新しいバージョンでデータ モデルを拡張することが困難になります。私は何か間違ったことをしていますか?私はSwiftが初めてです。

4

2 に答える 2

2

あなたはへの割り当てthumbが実行されていないことを示したので、問題は行にあると思います

name    = decoder.decodeObjectForKey("name") as String!

デコーダーは戻るnilことができ、文字列への変換を強制しています。この場合にデコーダが戻るnilと、エラーが発生します。次のような実装をお勧めします。

required convenience init(coder decoder: NSCoder) {
    self.init()

    horseID = decoder.decodeIntegerForKey("horseID")
    name    = decoder.decodeObjectForKey("name") as? String
    thumb   = decoder.decodeObjectForKey("thumb") as? UIImage
}

nilコーダーから返される可能性のある値を処理します。

于 2015-03-06T15:04:23.620 に答える
2

UIImage に強制キャストしようとしていますが、decodeObjectForKey が nil を返すとクラッシュします。オプションの値を取得するには、に置き換える必要があります。これにより、値が含まれているかどうかを確認できasます。as?

親指がオプションではなく、decodeObjectForKey で nil を取得した場合EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)、コメントで言及したエラー メッセージが表示されます。オプションではないものに nil を代入することはできません。型キャストで nil が返される場合に備えて、デフォルト値を指定することでこれを修正できます。

thumb   = decoder.decodeObjectForKey("thumb") as? UIImage ?? [default value here]
于 2015-03-06T14:05:31.453 に答える