Swift:无法将类型为"Self"的值转换为预期的参数类型"不安全指针<Void>"



我用[Uint8]数组做了一堆工作。但我经常不得不将这些对象重新转换为NSData对象,以便与 iOS 框架(如 CoreBluetooth)进行交互。所以我有很多代码可能看起来像这样:

var input:[UInt8] = [0x60, 0x0D, 0xF0, 0x0D]
let data = NSData(bytes: input, length: input.count)

厌倦了必须插入这个额外的let data = ...行,我想我只会用计算属性扩展这些数组来完成这项工作。然后我可以做这样的事情:

aBluetoothPeriperal.write(myBytes.nsdata, ...)

所以它基本上只是延长糖。我无法扩展 Array,但我可以扩展协议:

extension SequenceType where Generator.Element == UInt8 {
    var nsdata:NSData {
        return NSData(bytes: self, length: self.count)
    }
}

这将产生如下所示的错误:

Playground execution failed: MyPlayground.playground:3:24: error: cannot convert value of type 'Self' to expected argument type 'UnsafePointer<Void>' (aka 'UnsafePointer<()>')
                return NSData(bytes: self, length: self.count)
                                 ^~~~

可悲的是,我使用 Swift 的次数越多——我真的很喜欢 Swift 的一些东西——我就越想起我几年前尝试使用大量泛型和东西C++时试图理解大量无用编译器输出的负面经历。所以请欧比旺,帮我看看这里的光!

NSData(bytes:, length:)UnsafePointer<Void>作为第一个参数,并且您不能在此处传递任意SequenceType

您可以传递一个Array该将作为第一个数组元素。但是,不能保证Array元素存储在连续内存中。

因此:

  • 定义Array扩展而不是Sequence扩展。
  • 使用 withUnsafeBufferPointer() 方法获取指针到连续阵列存储。

可能的解决方案:

extension Array where Element : IntegerType {
    var nsdata : NSData {
        return self.withUnsafeBufferPointer {
            NSData(bytes: $0.baseAddress, length: self.count * strideof(Element))
        }
    }
}
let input:[UInt8] = [0x60, 0x0D, 0xF0, 0x0D]
print(input.nsdata) // <600df00d>

Swift 目前不允许限制数组扩展到具体类型:

extension Array where Element == UInt8 { }
// error: same-type requirement makes generic parameter 'Element' non-generic

因此,它被推广到任何符合IntegerType的元素。

对于序列,您可以先转换为数组:

let data = Array(myUInt8sequence).nsdata

这似乎可以做你想做的事。

protocol ByteOnly: IntegerType {}
extension UInt8: ByteOnly {}
extension Array where Element: ByteOnly {
    var n : NSData { return NSData(bytes: self, length: self.count) }
}
// does it work with UInt8
var input5:[UInt8] = [0x61, 0x0D, 0xF1, 0x0D]
let data5 = input5.n // YES
// does it work on ints?
var ints: [Int] = [3,4,5,6,7,8]
let idata5 = ints.n // no

相关内容