我想对存储在数组中的大量 CGPoint 实例执行一些数学运算,所以我想我会考虑使用 Accelerate 并首先将 CGPoint 与 AccelerateMutableBuffer 一致,然后扩展 Array 以使其一致。
经过一些试验和错误,我想出了以下内容,它编译没有任何错误,但是 vDSP.add(_:, _:, result:) 返回的结果不正确:变量 p 仍然是 .zero 在结尾。
我错过了什么?
非常感谢。
(您可以在 Playground 上尝试以下代码)
import Foundation
import CoreGraphics
import Accelerate
extension CGPoint: AccelerateMutableBuffer {
public typealias Element = Double
public var count: Int { 2 }
public func withUnsafeBufferPointer <R> (
_ body: (UnsafeBufferPointer<Element>) throws -> R
) rethrows -> R {
var varself = self
let ubp = withUnsafeBytes(of: &varself) { urbp in
urbp.bindMemory(to: Element.self)
}
return try body(ubp)
}
public mutating func withUnsafeMutableBufferPointer <R> (
_ body: (inout UnsafeMutableBufferPointer<Element>) throws -> R
) rethrows -> R {
var varself = self
var umbp = withUnsafeMutableBytes(of: &varself) { umrbp in
umrbp.bindMemory(to: Element.self)
}
return try body(&umbp)
}
}
let p1 = CGPoint(x: 1.5, y: 3.5)
let p2 = CGPoint(x: 0.5, y: 2.5)
var p: CGPoint = .zero
vDSP.add(p1, p2, result: &p)
p
编辑:我已经想通了。据我所知,这是正确的解决方案。它编译没有错误,运行没有问题,并给出正确的结果。因此,除非有人看到我没有看到的问题,否则我很乐意考虑解决这个问题。
先前实现的问题在于,在创建self
( var varself = self
) 的本地可变副本并对其进行操作时,它self
本身并没有改变。
import Foundation
import CoreGraphics
import Accelerate
extension CGPoint: AccelerateMutableBuffer {
public typealias Element = Double
public var count: Int { 2 }
public func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<Double>) throws -> R) rethrows -> R {
try Swift.withUnsafeBytes(of: self) { urbp in
try body(urbp.bindMemory(to: Double.self))
}
}
public mutating func withUnsafeMutableBufferPointer <R> (
_ body: (inout UnsafeMutableBufferPointer<Double>) throws -> R
) rethrows -> R {
try Swift.withUnsafeMutableBytes(of: &self) { umrbp in
var umbp = umrbp.bindMemory(to: Double.self)
return try body(&umbp)
}
}
}
let p1 = CGPoint(x: 1.5, y: 3.5)
let p2 = CGPoint(x: 0.5, y: 2.5)
var p: CGPoint = .zero
vDSP.add(p1, p2, result: &p)
p // (x: 2, y: 6) ✅