[英]Swift encode UInt8
为什么可以使用aCoder.encodeObject(myIntArray, forKey: "myKey")
对Int
数组进行编码aCoder.encodeObject(myIntArray, forKey: "myKey")
但是在尝试对UInt8
值数组进行编码时会出现编译器错误? 转换实际上并不算是戏剧性的,但是我将有56个不必要的位要编码...
encodeObject(_:forKey:)
在NSCoder
接受AnyObject?
类型:
func encodeObject(_ objv: AnyObject?, forKey key: String)
因此,如果将Int
数组传递给encodeObject
,则它将隐式转换为NSNumber
的NSArray
。 该机制在文档中进行了解释:
从Swift数组桥接到
NSArray
对象时, Swift数组中的元素必须与AnyObject
兼容 。 例如,[Int]
类型的Swift数组包含Int
结构元素。Int
类型不是类的实例,但是因为Int
类型桥接到NSNumber
类,所以Int
类型与AnyObject
兼容。 因此,您可以将[Int]
类型的Swift数组桥接到NSArray
对象。
另一方面, UInt8
不兼容AnyObject
:
以下所有类型都会自动桥接到
NSNumber
:
- 诠释
- UINT
- 浮动
- 双
- 布尔
这就是为什么您不能将[UInt8]
传递给encodeObject(_:forKey:)
。 您必须手动将其转换。
如果您担心编码数据的大小,则应使用NSData
或原始字节数组而不是NSArray
。 实际上,这取决于您所使用的NSCoder
,例如NSKeyedArchiver
:
// NSData
class Foo: NSObject, NSCoding {
var _array: [UInt8]
init(array:[UInt8]) {
_array = array
}
required init(coder aDecoder: NSCoder) {
let arrayData = aDecoder.decodeObjectForKey("array") as NSData
_array = Array(
UnsafeBufferPointer(
start: UnsafePointer<UInt8>(arrayData.bytes),
count: arrayData.length
)
)
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(
NSData(bytes: _array, length: _array.count),
forKey: "array"
)
}
}
// bytes
class Bar: NSObject, NSCoding {
var _array: [UInt8]
init(array:[UInt8]) {
_array = array
}
required init(coder aDecoder: NSCoder) {
var arrayLength:Int = 0
var buf = aDecoder.decodeBytesForKey("array", returnedLength: &arrayLength)
_array = Array(UnsafeBufferPointer(start: buf, count: arrayLength))
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeBytes(_array, length: _array.count, forKey: "array")
}
}
// NSArray of NSNumber
class Baz: NSObject, NSCoding {
var _array: [UInt8]
init(array:[UInt8]) {
_array = array
}
required init(coder aDecoder: NSCoder) {
_array = (aDecoder.decodeObjectForKey("array") as [NSNumber]).map({ $0.unsignedCharValue })
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(_array.map({NSNumber(unsignedChar:$0)}), forKey:"array")
}
}
然后:
let array = [UInt8](0 ..< 255)
let foo = Foo(array: array)
let bar = Bar(array: array)
let baz = Baz(array: array)
let fooData = NSKeyedArchiver.archivedDataWithRootObject(foo)
let barData = NSKeyedArchiver.archivedDataWithRootObject(bar)
let bazData = NSKeyedArchiver.archivedDataWithRootObject(baz)
fooData.length // -> 539
barData.length // -> 534
bazData.length // -> 3,454
let fooCopy = NSKeyedUnarchiver.unarchiveObjectWithData(fooData) as Foo
let barCopy = NSKeyedUnarchiver.unarchiveObjectWithData(barData) as Bar
let bazCopy = NSKeyedUnarchiver.unarchiveObjectWithData(bazData) as Baz
NSArray
大约消耗7倍的空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.