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)

projectile调试器显示和的两个不同值ballmass中的字段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
    ....
}

也将使这项工作。我的问题是,如果这是一个编译器错误,是否应该报告给 Apple,或者EXC_BAD_INSTRUCTION抛出代码是否应该编译?

4

1 回答 1

0

这是一个编译器错误(已在此处通过 Twitter 确认),但已经存在许多关于使用 Swift 返回的可选性的已知问题。

于 2015-02-02T20:29:33.270 回答