You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift如何修复AVCameraCalibrationData参考代码的withUnsafeBytes废弃警告

Swift深度校正类withUnsafeBytes废弃警告修复问题

经过多日调研,我编写了如下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)
        )
        
    }
}

该警告属于非常常见的废弃提示,但未找到适配本场景的解决方案,现存的可查用例均针对网络请求场景,直接套用现有方案会引入6处新错误,需要在不引入其他错误的前提下修复该废弃警告。


修复方案

Swift 5.0之后Data的withUnsafeBytes方法不再直接返回指定类型的指针,而是返回UnsafeRawBufferPointer,需要先手动绑定到目标类型内存再获取指针,仅需修改withUnsafeBytes闭包内的逻辑即可,无其他侵入性修改:

let mag: Float = table.withUnsafeBytes({ buffer in
    // 将原始字节缓冲区绑定为Float类型,获取首指针
    guard let tableValues = buffer.bindMemory(to: Float.self).baseAddress else {
        return 0
    }
    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]
    }
})

可选优化提示:原代码中计算径向距离时使用了平方相减的逻辑,按相机畸变校正的通用计算规则应为平方求和,如果后续校正结果不符合预期可检查sqrt(pow(dx_max,2) - pow(dy_max, 2))、sqrt(pow(vx,2) - pow(vy, 2))两处的符号逻辑


内容的提问来源于stack exchange,提问作者realkstrawn93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 17:45:03