【问题标题】:Swift structures causing undefined behaviour导致未定义行为的 Swift 结构
【发布时间】:2015-08-11 17:26:54
【问题描述】:

我正在编写一个使用 Metal 的程序。我正在使用结构定义统一缓冲区布局。当我在 swift 中声明结构时,它无法绘制。但是当我在 Objective-C 中声明结构并使用桥接头导入它时,它工作正常。计算的实际逻辑完全相同。唯一的变化是声明。以下是声明:

Objective-C 声明(这个有效):

struct Uniforms {
    struct Matrix4x4 modelViewMatrix;
    struct Matrix4x4 projectionMatrix;
    struct Matrix3x3 normalMatrix;
    struct Vector3 lightPosition;
};

还有 Swift 声明:

struct Uniforms {
    var modelViewMatrix: Matrix4x4!
    var projectionMatrix: Matrix4x4!
    var normalMatrix: Matrix3x3!
    var lightPosition: Vector3!
}

请注意,数学类型是在 Objective-C 中定义的结构,并充当 Swift 的包装器。

更多信息,这里是计算值并将它们发送到 Metal 的 Swift 代码:

// Declaration:
var uniforms: Uniforms!
...
// Part where I compute the values:
    self.uniforms = Uniforms()

    let eye = vector3Create(0.0, 5.0, 7.0)
    let center = vector3Create(0.0, 0.0, 0.0)
    let up = vector3Create(0.0, 1.0, 0.0)
    self.uniforms.modelViewMatrix = MathOperations.lookAt(eye, center: center, up: up)

    let aspect = Float(self.view.bounds.size.width / self.view.bounds.size.height)
    self.uniforms.projectionMatrix = MathOperations.perspective(45.0, aspect: aspect, near: 0.01, far: 100.0)
    self.uniforms.normalMatrix = getMatrix3x3FromMatrix4x4(self.uniforms.modelViewMatrix)
    self.uniforms.lightPosition = vector3Create(0.0, 5.0, 7.0)

    self.vertexBuffer = device.newBufferWithBytes(self.vertexArray, length: self.vertexArray.count * sizeof(Float), options: .CPUCacheModeDefaultCache)
    self.uniformBuffer = device.newBufferWithBytes(&self.uniforms, length: sizeof(Uniforms), options: .CPUCacheModeDefaultCache)

抱歉所有代码,但请帮助。谢谢。

【问题讨论】:

  • 你为什么要在 Swift struct optionals 中设置 4 个字段?
  • 谢谢!起初我将它们设为可选,因为我认为由于它们以声明开始,因此一开始就需要为 nil。但现在我使它们不可为空,并用构造函数填充结构。现在它起作用了!顺便说一句,为什么 Metal 不接受选项?即使是可选的,GPU 帧捕获也会在缓冲区中显示正确的数据。
  • 好的,我添加了更多信息作为答案。如果它确实解决了您的问题,请接受它。

标签: objective-c swift struct metal


【解决方案1】:

我试图在这里解释我添加到问题中的评论,这看起来是一个正确的答案。

转换此Objective-C代码的正确方法:

struct Matrix4x4 modelViewMatrix;

Swift不是这个

var modelViewMatrix: Matrix4x4!

因为这样我们不会创建Matrix4x4 类型的变量。相反,我们正在创建一个 Optional 类型的变量 Matrix4x4

这意味着在 Swift 中变量 modelViewMatrix 能够假定 nil 值,而在 Objective-C 中则不能。

让我们记住,在 Objective-C 中,变量的类型为 struct 不能为零。

所以将原始语句从Objective-C 翻译成Swift 的正确方法如下:

var modelViewMatrix: Matrix4x4

【讨论】:

    猜你喜欢
    • 2017-06-10
    • 2016-04-09
    • 2014-08-23
    • 2014-08-11
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多