0

構造体、クラス、および型付きクロージャーが与えられた場合:

struct Vector3d {
    var X:Double
    var Y:Double
    var Z:Double
}

class Sprite {

    var mass: Double = 0.0

    init(mass: Double) {
        self.mass = mass
    }
}

typealias ForceComputation =
    (NSTimeInterval, Sprite) -> Vector3d?

次のコードは でクラッシュしEXC_BAD_INSTRUCTIONます:

// Construct an instance of the class to call back with
var ball = Sprite(mass: 3.0)

// Create an instance of closure
var gravity:ForceComputation = { (projectile:Sprite) -> Vector3d in
    // use this line to close ball so it's available in debugger
    var mass1 = ball.mass

    // use mass1 in following line to ensure not optimized out
    // (ignore invalid gravity formula)
    var verticleAcceleration = -9.8 * projectile.mass * mass1

    return Vector3d(X:0.0, Y:verticleAcceleration, Z:0.0)
}

// activate the closure
gravity(ball)

デバッガーには、 と の 2 つの異なる値が表示されprojectileますball。のフィールドmassprojectile無効です。ただし、クロージャーの内側と外側の両方massで有効です。ballコンパイラ エラーや警告はありませんが、実行EXC_BAD_INSTRUCTION時にスローprojectile.massされますか?

ForceComputation誤解を招くデバッグ データにもかかわらず、問題はクロージャのパラメータとは何の関係もありません。問題は、返された構造体が次のオプションとして定義されていることですtypealias

typealias ForceComputation =
    (Sprite) -> Vector3d?

ただし、オプションではない戻り値の型で構築されています ( ?afterがないことに注意してくださいVector3d):

// Create an instance of closure
var gravity:ForceComputation = { (projectile:Sprite) -> Vector3d in
    ....
}

上記のコードを変更して入力を削除します。

// Create an instance of closure
var gravity = { (projectile:Sprite) -> Vector3d in
    ....
}

コードを修正するか、戻り値の型がオプションであることを確認します ( の?後のメモVector3d):

// Create an instance of closure
var gravity:ForceComputation = { (projectile:Sprite) -> Vector3d? in
    ....
}

もこれを機能させます。EXC_BAD_INSTRUCTION私の質問は、これがコンパイラのバグであり、Apple に報告する必要があるかどうか、またはスローされたコードをコンパイルする必要がある理由があるかどうかです。

4

1 に答える 1

0

これはコンパイラのバグです (ここの Twitter で確認済み) が、Swift での戻り値のオプション性に関する既知の問題がすでにいくつかあります。

于 2015-02-02T20:29:33.270 に答える