Почему можно кодировать массив из Int
с использованием aCoder.encodeObject(myIntArray, forKey: "myKey")
, но вы получаете ошибку компилятора при попытке кодирования массива значений UInt8
? Конверсия на самом деле не драматична, но я бы 56 ненужных биты для кодирования ...Swift encode UInt8
ответ
encodeObject(_:forKey:)
в NSCoder
принимаю AnyObject?
типа:
func encodeObject(_ objv: AnyObject?, forKey key: String)
Так что, если вы передаете массив Int
в encodeObject
, он неявно преобразуется до NSArray
от NSNumber
s. Этот механизм объясняется в the document:
Когда мост от Swift массива в
NSArray
объекта, элементы в Swift массива должны быть совместимыAnyObject
. Например, массив Swift типа[Int]
содержит элементы структурыInt
. ТипInt
не является экземпляром класса, а потому, что мостыInt
относятся к классуNSNumber
, типInt
-AnyObject
. Таким образом, вы можете связать массив Swift типа[Int]
с объектомNSArray
.
С другой стороны UInt8
является неAnyObject
совместимы:
Все следующие типы автоматически мостиком
NSNumber
:
- Int
- UInt
- Float
- Double
- Bool
Вот почему вы не можете передать [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
составляет около 7x пространства потребления.
- 1. Подстрочный диапазон [UInt8] - Swift
- 2. Uint8 Массив для струнных Swift
- 3. Convert [UInt32] -> [UInt8] -> [[UInt8]] в Swift
- 4. Swift encode URL-адрес WhatsApp
- 5. Как конвертировать персонаж в Uint8 в Swift
- 6. Преобразование UIImage в массив UInt8 в Swift
- 7. Swift конвертировать десятичную строку в UInt8-Array
- 8. Двойник не конвертируемый в Uint8, Swift ошибка
- 9. Swift ошибка: «двойник не конвертируемый в Uint8»
- 10. 'int?' не идентичен «Uint8» в swift
- 11. Swift 2.1 [UInt8] --utf8 -> String?
- 12. Преобразование [UInt8]? to image in IOs swift
- 13. Swift/Objective-C ASN1 encode public key
- 14. uint8 srcBuf [] и uint8 * srcBuf
- 15. Переполнение при uint64 = uint8 * uint8
- 16. Данные против [UInt8]
- 17. Swift Equifant для Python's - hash.digest(). Encode ('base64'). Strip()?
- 18. Encode/Decode перечисление для Swift (Xcode 6.1)
- 19. NSData от UInt8
- 20. URI encode и HTML encode
- 21. 'bool' не конвертируется в 'uint8'
- 22. Приращение переменной типа UInt8 внутри цикла for
- 23. Преобразование строки в UnsafeMutablePointer <UInt8> Swift
- 24. Swift завышен [UInt8] не сработает с miniz lib
- 25. ли Uint8 в Swift действительно эквивалент uint8_t от C
- 26. Convert UInt8 ?, String, Int to String type using Swift
- 27. Как преобразовать UInt8 в Anyobject в Swift 2.3
- 28. Swift: Создать массив UInt8 с определенным числом значений
- 29. Массив UInt8 для Base64 String Swift (пример Java)
- 30. Swift 3.0 конвертировать данные в массив <UInt8>
UInt8 может быть получен из объектива c и не является подклассом кодируемого объекта, если у вас нет тонких ints. Я не вижу проблемы с использованием собственного swift-типа. –
BTW, как вы можете преобразовать его только с 56 бит (7 байт)? Самый короткий путь, насколько я могу придумать, это '.map {Int ($ 0)}', 13 байт. – rintaro
@ rintaro Я не имел в виду массив, но тип UInt8 по сравнению с Int – borchero