1.Swift中,将Byte类型转化成char类型
例:
let b:Byte = 97
println(Character(UnicodeScalar(Int(b))))
当然可以扩展Byte类
extension Byte {
func char() -> Character {
return Character(UnicodeScalar(Int(self)))
}
}
println(b.char()) // prints "a"
println(98.char()) // prints "b"
I'm now finding that if I have a struct with bytes mixes with a byte array it doesn't pack correctly.
Example Code:
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)
returns correct array with values of [72,69,76,76,79]
However, when I convert this struct to NSData using:
// Struct to NSData.
var data = NSData(
bytes: & myStruct,
length: sizeof(exampleStruct)
)
I get unexpected results of: "data: <01020304 00000000 108c91fd a87f0000>". I was expecting "data: <01020304 48454c4c 4f>"
It seems like this is because the [Byte] Array length is not set. Can it be set in SWIFT? When I try the following:
struct exampleStruct {
var ModelNumber: Byte
var MajorVersion: Byte
var MinorVersion: Byte
var Revision: Byte
var Message: Byte[5] // << Set array length 5
}
I get a warning that states: "Fixed-length arrays are not yet supported".
Anyway to work around this limitation?
以下是解决方案: var Message: [Byte]
declares a variable of the type 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 ...
}
so this is not just a "C array" of bytes. The actual storage is opaque and only accessible through methods and properties.
You can define a tuple of fixed size:
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>
However, I don't think that Swift makes any guarantees about the binary representation of its structures, so this may break in the future.
3.NSData from Byte array in Swift (NSData用[Byte]初始化) I'm trying to create an NSData
var
from an array of bytes.
In Obj-C I might have done this:
NSData *endMarker = [[NSData alloc] initWithBytes:{ 0xFF, 0xD9 }, length: 2]
I can't figure out a working equivalent in Swift.
以下是解决方案: NSData
has an init method that looks like init(bytes: ConstUnsafePointer<()>, length: Int)
. A ConstUnsafePointer
parameter can accept a variety of different things, including a simple Swift array, so you can use pretty much the same syntax as in Objective-C. When you pass the array, you need to make sure you identify it as a Byte
array or Swift's type inference will assume you mean to create an Int
array.
var endMarker = NSData(bytes: [0xFF, 0xD9] as [Byte], length: 2)
You can read more about unsafe pointer parameters in Apple's Interacting with C APIsdocumentation.
二、
var foo : Byte[] = [0xff, 0xD9]
var data = NSData(bytes: foo, length: foo.count)
println("\(data)")
outputs: ff d9
var data = NSData(bytes: [0xFF, 0xD9] as Byte[], length: 2)
println("\(data)")
outputs: ff d9
Edit: Ah, you have to write 'as Byte[]', so then the results are the same
4.Create an Array in Swift from an NSData Object(在Swift中将一个NSData数据与数组相互转换)import Foundation
var arr : UInt32[] = [32,4,123,4,5,2];
let data = NSData(bytes: arr, length: arr.count * sizeof(UInt32))
println(data) //data looks good in the inspector
// now get it back into an array?
// the number of elements:
let count = data.length / sizeof(UInt32)
// create array of appropriate length:
var array = [UInt32](count: count, repeatedValue: 0)
// copy bytes into array
data.getBytes(&array, length:count * sizeof(UInt32))
println(array)
// Output: [32, 4, 123, 4, 5, 2]