【发布时间】:2015-02-02 17:52:41
【问题描述】:
给定一个结构、一个类和类型闭包:
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)
调试器显示projectile 和ball 的两个不同值。 projectile 中的字段mass 无效。但是mass 对闭包内部和外部的ball 都有效。没有编译器错误或警告但在执行projectile.mass 时抛出EXC_BAD_INSTRUCTION?
尽管有误导性的调试数据,但问题与ForceComputation 闭包的参数无关。问题是返回的结构在typealias 中定义为可选:
typealias ForceComputation =
(Sprite) -> Vector3d?
但使用非可选返回类型构造(注意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
....
}
也会使这项工作。我的问题是,如果这是一个编译器错误,是否应该向 Apple 报告,或者是否有原因 EXC_BAD_INSTRUCTION 抛出的代码应该编译?
【问题讨论】:
标签: swift compiler-bug