Swift 3.0+如何将UnsafeMutableRawPointer!转为UnsafeMutablePointer<Float>
解决Swift 2到3/4迁移中Accelerate库的类型转换问题
我帮你梳理下这类迁移里最棘手的Accelerate库类型转换问题,毕竟Swift 3+对指针模型和类型系统做了大幅调整,之前Swift 2的写法在新语法里会频繁报错。结合你提到的图像算术运算场景,我给你具体的修复思路和代码示例:
核心变化点先搞清楚
Swift 3+和Swift 2在Accelerate库使用上的核心差异集中在这几点:
- 指针类型体系重构:区分了
UnsafeRawPointer/UnsafeMutableRawPointer和类型化指针(比如UnsafePointer<UInt8>),原来直接强制转换的写法失效了 - 内存大小获取:
sizeof(T)被替换成MemoryLayout<T>.size/MemoryLayout<T>.stride - 结构体参数传递:原来直接传结构体地址的写法,现在需要配合
inout修饰符或者显式的指针绑定
拿图像加法函数举例子修复
假设你原来Swift 2的代码大概是这样的:
import Accelerate public typealias Pixel_8 = UInt8 public func addImages(image1: vImage_Buffer, image2: vImage_Buffer, result: vImage_Buffer) -> vImage_Error { let pixelSize = UInt32(sizeof(Pixel_8)) return vImage_Add_Planar8(&image1, &image2, &result, pixelSize) }
转换成Swift 3/4的正确写法应该是这样:
import Accelerate public typealias Pixel_8 = UInt8 public func addPlanar8Images(image1: inout vImage_Buffer, image2: inout vImage_Buffer, result: inout vImage_Buffer) -> vImage_Error { // 先做参数合法性校验(新语法里建议加上,避免崩溃) guard image1.width == image2.width, image1.height == image2.height, image1.rowBytes == image2.rowBytes, image1.rowBytes == result.rowBytes else { return vImage_Error(kvImageInvalidParameter) } // 替换sizeof为MemoryLayout let pixelSize = UInt32(MemoryLayout<Pixel_8>.size) // Swift 3+允许直接给C函数传递&修饰的inout参数,自动转为UnsafeMutablePointer return vImage_Add_Planar8(&image1, &image2, &result, pixelSize) }
处理更复杂的指针转换场景
如果你的代码里涉及到vImage_Buffer.data的直接操作(比如手动访问像素数据),原来Swift 2的写法:
let pixelPtr = UnsafeMutablePointer<UInt8>(imageBuffer.data)
在Swift 3+里要改成这样(因为data现在是UnsafeMutableRawPointer?类型):
guard let pixelPtr = imageBuffer.data?.assumingMemoryBound(to: UInt8.self) else { // 处理data为空的异常情况 return vImage_Error(kvImageInvalidParameter) }
额外的迁移小提示
- 对于
vImageBuffer_Init这类初始化函数,要确保传入的bitsPerPixel是UInt32类型,比如UInt32(8 * MemoryLayout<Pixel_8>.size) - 如果遇到Xcode提示“Cannot convert value of type 'UnsafeMutablePointer
' to expected argument type 'UnsafeMutableRawPointer'”,可以用 UnsafeMutableRawPointer(pointer)来转换 - 尽量保留原有的Accelerate函数逻辑,只调整类型和指针相关的写法,Accelerate的核心算法逻辑在Swift 3+里没有变化
内容的提问来源于stack exchange,提问作者Keen R.D.
相关产品推荐
相关产品推荐

