2014-12-04 4 views
2

В продолжение моей должности: Using Structs (Bytes) with SWIFT - Struct to NSData and NSData to StructИспользование структур (включает в себя массив байтов) с SWIFT - STRUCT к NSData и NSData к STRUCT

Я теперь находя, что если у меня есть-структуру с байтами смешивается с массивом байтов он не упаковывается правильно.

Пример кода:

struct exampleStruct { 
    var ModelNumber: Byte 
    var MajorVersion: Byte 
    var MinorVersion: Byte 
    var Revision: Byte 
    var Message: [Byte] 
} 

var myStruct = exampleStruct (
    ModelNumber: 1, 
    MajorVersion: 2, 
    MinorVersion: 3, 
    Revision: 4, 
    Message: [0x48, 0x45, 0x4C, 0x4C, 0x4F] // HELLO 
) 

println(myStruct.Message) возвращает правильный массив со значениями [72,69,76,76,79]

Однако, когда я преобразовать эту структуру, чтобы NSData с помощью:

// Struct to NSData. 
var data = NSData(
    bytes: & myStruct, 
    length: sizeof(exampleStruct) 
) 

Получать неожиданные результаты: "данные: < 01020304 00000000 108c91fd a87f0000>". Я ожидал "данных: < 01020304 48454c4c 4f>"

Похоже, это потому, что длина массива [Byte] не установлена. Может ли он быть установлен в SWIFT? При попытке совершить следующее:

struct exampleStruct { 
    var ModelNumber: Byte 
    var MajorVersion: Byte 
    var MinorVersion: Byte 
    var Revision: Byte 
    var Message: Byte[5] // << Set array length 5 
} 

У меня появляется предупреждение, в котором говорится: «Массивы фиксированной длины еще не поддерживаются».

В любом случае, чтобы обойти это ограничение?

+0

'[Byte]' - Swift 'struct Array', а не массив C. –

ответ

2

var Message: [Byte] объявляет переменную типа struct Array:

struct Array<T> : MutableCollectionType, Sliceable { 

    /// The type of element stored by this `Array` 
    typealias Element = T 

    /// Always zero, which is the index of the first element when non-empty. 
    var startIndex: Int { get } 

    /// A "past-the-end" element index; the successor of the last valid 
    /// subscript argument. 
    var endIndex: Int { get } 
    subscript (index: Int) -> T 

    // ... and much more ... 
} 

, так что это не просто "C массив" байтов. Фактическое хранилище непрозрачно и доступно только способами и свойствами.

Вы можете определить кортеж фиксированного размера:

struct exampleStruct { 
    var ModelNumber: Byte 
    var MajorVersion: Byte 
    var MinorVersion: Byte 
    var Revision: Byte 
    var Message: (Byte, Byte, Byte, Byte, Byte) 
} 

var myStruct = exampleStruct (
    ModelNumber: 1, 
    MajorVersion: 2, 
    MinorVersion: 3, 
    Revision: 4, 
    Message: (0x48, 0x45, 0x4C, 0x4C, 0x4F) // HELLO 
) 
var data = NSData(
    bytes: &myStruct, 
    length: sizeof(exampleStruct) 
) 

println(data) // <01020304 48454c4c 4f> 

Однако, я не думаю, что Свифт делает какие-либо гарантии о двоичном представлении его структур, так что это может нарушить в будущем ,

+0

Это замечательно - Спасибо! По какой-то причине я считаю, что SWIFT больше похож на C, чем на самом деле. – Mavro

+0

@ Мавро: Добро пожаловать. - Если вам требуется четко определенное представление (например, для обмена данными), вы, вероятно, более безопасны, определяя структуру C и импортируя ее в Swift (или определяете свои собственные функции маршалинга). –