Swift EXC_BAD_INSTRUCTION调用typealias / typed / defined closure没有编译器错误或警告

时间:2015-02-02 17:52:41

标签: swift compiler-bug

给定结构,类和类型化闭包:

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)

调试器为projectileball显示两个不同的值。 mass中的字段projectile无效。但是mass对于闭包内外的ball都有效。没有编译器错误或警告,但执行EXC_BAD_INSTRUCTION时会抛出projectile.mass

尽管有误导性的调试数据,但问题与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投掷代码应该编译的原因?

1 个答案:

答案 0 :(得分:0)

这是一个编译器错误(通过Twitter here确认)但是围绕使用Swift返回的可选项已经存在许多已知问题。