【发布时间】:2020-09-20 14:15:12
【问题描述】:
Swift 提供 Data 和 [UInt8] 类型,它们的作用非常相似。
- 两者有什么区别?
- 在设计新的 API 时,首选的类型是什么?
【问题讨论】:
-
我会说
Data(~NSData) 是对象并提供了很多有用的方法。但这取决于您是否需要它们。
Swift 提供 Data 和 [UInt8] 类型,它们的作用非常相似。
【问题讨论】:
Data (~NSData) 是对象并提供了很多有用的方法。但这取决于您是否需要它们。
[UInt8] 本质上是一个字节数组,一个字节(我相信你知道)由 8 位组成。虽然 NSData 不仅仅是一个字节数组,但它的底层结构是基于一个字节数组。例如,您可以使用data.bytes 等方法轻松地在它们之间进行转换。
在设计 API 方面,我个人建议您使用 NSData 来设计它们,因为它通过简单的字节数组提供了所有额外的功能。苹果已经为你做了很多跑腿工作,为什么还要自己做呢?
【讨论】:
Data 还是仅仅与ObjC 部件交互?你有使用 Data 和 [UInt8] 的流行库吗?
Data 对那些人来说很受欢迎吗?
data.base64EncodedStringWithEncoding(NSUTF8StringEncoding) 轻松转换为
[UInt8]切换到Data,至少在Swift Protobuf项目中:github.com/apple/swift-protobuf/issues/129github.com/apple/swift-protobuf/pull/134
我更喜欢在大多数情况下使用Data,但[UInt8] 有一个明显的优势:您可以将它直接传递给需要指向字节的指针的函数,例如C 函数,而对于Data,您必须做更多的事情体操。下面的代码演示了不可变数组和可变数组以及Data 对象的区别。
func takesAPointer(_ p: UnsafePointer<UInt8>) {
// ...
}
let a: [UInt8] = [1, 2, 3]
takesAPointer(a)
let d = Data([1, 2, 3])
d.withUnsafeBytes {
let p = $0.bindMemory(to: UInt8.self).baseAddress!
takesAPointer(p)
}
func takesAMutablePointer(_ p: UnsafeMutablePointer<UInt8>) {
// ...
}
var b: [UInt8] = [1, 2, 3]
takesAMutablePointer(&b)
var e = Data([1, 2, 3])
e.withUnsafeMutableBytes {
let p = $0.bindMemory(to: UInt8.self).baseAddress!
takesAMutablePointer(p)
}
【讨论】: