2016-06-20 8 views
4

Mit NSMutableData könnte ich ein Array von Int's oder Float erstellen und diese auf der Festplatte speichern.Wie man Int an die neue Datenstruktur anfügt (Swift 3)

protocol BinaryConvertible 
{ 
    init() 
} 

extension Int : BinaryConvertible {} 


struct Storage<T: BinaryConvertible> 
{ 
let data = NSMutableData() 

func append(value: T) 
{ 
    var input = value 
    data.append(&input, length: sizeof(T)) 
} 

func extract(index: Int) -> T 
{ 
    var output = T() 
    let range = NSRange(location: index * sizeof(T), length: sizeof(T)) 
    data.getBytes(&output, range: range) 
    return output 
} 
} 

Swift 3 hat eine neue Art, die DataNSData unter der Haube verwendet. Wie String und NSString. Ich kann nicht herausfinden, wie z. a Double mit den neuen Methoden.

Die Append-Funktion erwartet nun eine UnsafePointer<UInt8>, aber wie erstellen Sie dies aus einer Double oder irgendeine zufällige Struktur für diese Angelegenheit?

+1

Mögliche Duplikat [Werfen Sie einen Swift-Struktur zu UnsafeMutablePointer ] (http://stackoverflow.com/questions/29556610/cast-a-swift-struct-to-unsafemutualpointervoid) – Alexander

+0

Ich glaube nicht. In swift 3 Data erwartet UnsafePointer . Notieren Sie den UInt8-Typ. Alles, was ich bisher gefunden habe, beschäftigt sich mit UnsafePointer Zeigern. Ich muss die Bytes holen, damit ich sie auf die Festplatte schreiben kann, und später diese Bytes wieder lesen. – user965972

+0

Es kann gegossen werden – Alexander

Antwort

10

Das Arbeiten mit Zeigern ist eines meiner am wenigsten bevorzugten Dinge in Swift, aber es bietet auch eine gute Lernerfahrung. Dies funktioniert für mich:

struct Storage<T: BinaryConvertible> 
{ 
    var data = Data() 

    mutating func append(value: T) 
    { 
     var input = value 
     let buffer = UnsafeBufferPointer(start: &input, count: 1) 
     self.data.append(buffer) 
    } 

    func extract(index: Int) -> T 
    { 
     let startIndex = index * sizeof(T) 
     let endIndex = startIndex + sizeof(T) 

     var output = T() 
     let buffer = UnsafeMutableBufferPointer(start: &output, count: 1) 
     let _ = self.data.copyBytes(to: buffer, from: startIndex..<endIndex) 

     return output 
    } 
} 

var s = Storage<Double>() 
s.append(value: M_PI) 
s.append(value: 42) 
s.append(value: 100) 

print(s.extract(index: 0)) 
print(s.extract(index: 1)) 
print(s.extract(index: 2)) 
1

Ich mag + verwenden oder + =

public protocol DataConvertible { 
    static func + (lhs: Data, rhs: Self) -> Data 
    static func += (lhs: inout Data, rhs: Self) 
} 

extension DataConvertible { 
    public static func + (lhs: Data, rhs: Self) -> Data { 
     var value = rhs 
     let data = Data(buffer: UnsafeBufferPointer(start: &value, count: 1)) 
     return lhs + data 
    } 

    public static func += (lhs: inout Data, rhs: Self) { 
     lhs = lhs + rhs 
    } 
} 

extension UInt8 : DataConvertible { } 
extension UInt16 : DataConvertible { } 
extension UInt32 : DataConvertible { } 

extension Int : DataConvertible { } 
extension Float : DataConvertible { } 
extension Double : DataConvertible { } 

extension String : DataConvertible { 
    public static func + (lhs: Data, rhs: String) -> Data { 
     guard let data = rhs.data(using: .utf8) else { return lhs} 
     return lhs + data 
    } 
} 

extension Data : DataConvertible { 
    public static func + (lhs: Data, rhs: Data) -> Data { 
     var data = Data() 
     data.append(lhs) 
     data.append(rhs) 

     return data 
    } 
} 

Probe

var data = Data() 
data += 1 
data += 1.0 
data += UInt8(1) 
data += "1"