您可能想要查看名为
RawData的新工具,作者只是在试验这个想法,因此不要认为它已经经过充分测试或其他方面的保证,有些功能甚至还没有实现。它基本上是一个Swift-y包装器,用于处理原始数据,即一系列字节。
使用此扩展程序,您可以使用
NSData
实例进行初始化:
extension RawData {
convenience init(data: NSData) {
self.init(UnsafeMutableBufferPointer(start: UnsafeMutablePointer(data.bytes), count: data.length))
}
}
您需要这样调用它:
let data = "Hello, data!".dataUsingEncoding(NSASCIIStringEncoding)!
let rawData = RawData(data: data)
编辑:回答你的问题:
事实上,数据可以非常大。一般来说,我们不希望复制大量数据,因为存储空间很宝贵。使用 [UInt8]
数组和 NSData
实例之间的区别在于,每次将数组传递给函数时都会进行复制,每次进行赋值时也会进行复制。对于大量数据来说,这并不理想。
1)如果你想要最本地化、最安全的方式,而又不需要任何第三方库(例如上述提到的那个),可以这样做:
let data = UnsafeMutableBufferPointer(start: UnsafeMutablePointer(data.bytes), count: data.length)
我知道听起来不太安全,但请相信我它是安全的。你可以像使用普通数组一样使用它:
let data = "Hello, data!".dataUsingEncoding(NSASCIIStringEncoding)!
let bytes = UnsafeMutableBufferPointer(start: UnsafeMutablePointer<UInt8>(data.bytes), count: data.length)
for byte in bytes {}
bytes.indexOf(0)
bytes.maxElement()
并且它不会在你传递数据时复制数据。
2)UnsafeMutablePointer<Void>
在这种情况下确实非常类似于 C,它表示指针序列中的起始值(也称为基值)。 Void
类型也来自 C,它表示指针不知道它存储的是什么类型的值。您可以将各种类型的指针强制转换为您期望的类型,如此进行:UnsafeMutablePointer<Int>(yourVoidPointer)
(这不应该崩溃)。如前所述,您可以使用 UnsafeMutableBufferPointer
以其类型集合的形式使用它。 UnsafeMutableBufferPointer
只是您的基指针和长度的包装器(这解释了我使用的初始化程序)。
直接将数据解码到您的结构体的方法确实有效,结构体的属性在编译时之后仍按正确顺序排列,并且结构体的大小恰好等于其存储的属性的总和。对于像您的简单数据这样的数据,这完全可以。还有一种替代方式:使用 NSCoding
协议。优点:更安全。缺点:您必须子类化 NSObject。我认为您应该坚持现在的方式。但是我会改变一件事,将结构体的解码放在结构体本身中并使用 sizeof
。将其设置为:
struct TreeDescription {
var id:UInt32 = 0x00000000
var channel:UInt8 = 0x00
var rssi:UInt8 = 0x00
init(data: NSData) {
data.getBytes(&self, length: sizeof(TreeDescription))
}
}
另外编辑:您可以使用方法memory
从Unsafe(Mutable)Pointer<T>
获取底层数据,其返回类型为T
。如果需要,您可以始终通过将Int
添加/减去到指针上来移动指针(例如获取下一个值)。
回答您的评论:您使用&
来传递一个inout
变量,它可以在函数内部修改。因为inout
变量基本上与传递指针相同,所以Swift开发人员决定使其可以传递&value
作为期望UnsafeMutablePointer
的参数。演示:
func inoutArray(inout array: [Int]) {}
func pointerArray(array: UnsafeMutablePointer<Int>) {}
var array = [1, 2, 3]
inoutArray(&array)
pointerArray(&array)
这也适用于结构体(以及其他一些东西)。
NSData
。例如:NSData(&myStruct, sizeof(myStruct))
,它可以正常工作。我的天真的观察是,在变量前面加上 & 与 C 中的方式类似。 - Travis Griggs