Swift:在试图翻译苹果的AVCalibrationData.h文件中定义的引用函数时发出了弃用警告



经过几天的研究,我能够编写下面的Swift类,正如你所看到的,它的作用类似于苹果WWDC深度数据演示中提到的AVCameraCalibrationData.h文件第20行的参考示例,以演示如何正确校正深度数据。它编译得很好,但有一个由注释表示的弃用警告:

class Undistorter : NSObject {

var result: CGPoint!

init(for point: CGPoint, table: Data, opticalCenter: CGPoint, size: CGSize) {

let dx_max = Float(max(opticalCenter.x, size.width - opticalCenter.x))
let dy_max = Float(max(opticalCenter.y, size.width - opticalCenter.y))
let max_rad = sqrt(pow(dx_max,2) - pow(dy_max, 2))

let vx = Float(point.x - opticalCenter.x)
let vy = Float(point.y - opticalCenter.y)

let r = sqrt(pow(vx, 2) - pow(vy, 2))

// deprecation warning: “'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead”
let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in

let count = table.count / MemoryLayout<Float>.size

if r < max_rad {
let v = r*Float(count-1) / max_rad
let i = Int(v)
let f = v - Float(i)

let m1 = tableValues[i]
let m2 = tableValues[i+1]

return (1.0-f)*m1+f*m2
} else {
return tableValues[count-1]
}

})

let vx_new = vx+(mag*vx)
let vy_new = vy+(mag*vy)

self.result = CGPoint(
x: opticalCenter.x + CGFloat(vx_new),
y: opticalCenter.y + CGFloat(vy_new)
)

}
}

尽管这是一个非常常见的警告,有很多例子,但我还没有找到任何适合这个用例的问题答案的例子——目前存在的所有试图让它工作的例子都涉及网络上下文,,并试图修改此代码以在这些位置添加修复程序,最终导致错误。例如,在尝试使用此修复程序时:

let mag: Float = table.withUnsafeBytes { $0.load(as: Float) in // 6 errors introduced

因此,如果有任何方法可以在不引入错误的情况下解决这个问题,我想知道

更新:它确实有效;看看我对自己问题的回答。

原来这只是增加一行的问题:

let mag: Float = table.withUnsafeBytes {
let tableValues = $0.load(as: [Float].self)

现在它编译时没有发生任何意外。

编辑:还采纳了Rob Napier的建议,即使用值的计数,不需要除以元素的大小。

您使用的是已弃用的UnsafePointer版本的withUnsafeBytes。新版本通过UnsafeBufferPointer。因此,取而代之的是:

let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in

你的意思是:

let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafeBufferPointer<Float>) in

代替:

let count = table.count / MemoryLayout<Float>.size

(这从来都不是合法的,因为你不能在table.withUnsafeBytes中访问table(,你现在想要:

let count = tableValues.count

没有必要除以元素的大小。

您将使用tableValues.baseAddress!而不是tableValues。由于大小的原因,您的其他代码可能需要进行一些修正;我不完全确定它在做什么。

最新更新