構造体、クラス、および型付きクロージャーが与えられた場合:
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
。のフィールドmass
がprojectile
無効です。ただし、クロージャーの内側と外側の両方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 に報告する必要があるかどうか、またはスローされたコードをコンパイルする必要がある理由があるかどうかです。