Swift 结构到 NSData 并返回 [英] Swift structs to NSData and back

查看:69
本文介绍了Swift 结构到 NSData 并返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构体,其中包含一个结构体和一个 NSObject,我想将其序列化为一个 NSData 对象:

I have a struct containing a struct and an NSObject that I want to serialize into an NSData object:

struct Packet {
  var name: String
  var index: Int
  var numberOfPackets: Int
  var data: NSData
}

var thePacket = Packet(name: name, index: i, numberOfPackets: numberOfPackets, data: packetData)

如何最好地将数据包序列化为 NSData,以及如何最好地反序列化它?

How do I best serialize the Packet into an NSData, and how do I best deserialize it?

使用

var bufferData = NSData(bytes: & thePacket, length: sizeof(Packet))

of 只给了我名字和数据的指针.我正在探索 NSKeyedArchiver,但后来我不得不将 Packet 设为一个对象,而我更愿意将其保留为一个结构体.

of only gives me the pointers of name and data. I was exploring NSKeyedArchiver, but then I'd have to make Packet an object, and I'd prefer to keep it a struct.

干杯

尼克

推荐答案

没有真正得到任何反馈,这是我最终得到的解决方案:

Not really getting any feedback, this is the solution I ended up with:

  1. 为我的结构制作 encode()decode() 函数
  2. Int 更改为 Int64,以便 Int 在 32 位和 64 位平台上具有相同的大小
  3. 有一个没有 String 或 Data 的中间结构 (ArchivedPacket),只有 Int64
  1. Make encode() and decode() functions for my struct
  2. Change Int to Int64 so the Int has the same size on 32-bit and 64-bit platforms
  3. Have an intermediate struct (ArchivedPacket) that has no String or Data, but only Int64

这是我的代码,我将非常感谢您的反馈,特别是如果有不那么麻烦的方法来做到这一点:

Here is my code, I would be very grateful for your feedback, especially if there are less cumbersome ways to do this:

public struct Packet {
    var name: String
    var index: Int64
    var numberOfPackets: Int64
    var data: NSData

    struct ArchivedPacket {
        var index : Int64
        var numberOfPackets : Int64
        var nameLength : Int64
        var dataLength : Int64
    }

    func archive() -> NSData {

        var archivedPacket = ArchivedPacket(index: Int64(self.index), numberOfPackets: Int64(self.numberOfPackets), nameLength: Int64(self.name.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)), dataLength: Int64(self.data.length))

        var metadata = NSData(
            bytes: &archivedPacket,
            length: sizeof(ArchivedPacket)
        )

        let archivedData = NSMutableData(data: metadata)
        archivedData.appendData(name.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!)
        archivedData.appendData(data)

        return archivedData
    }

    func unarchive(data: NSData!) -> Packet {
        var archivedPacket = ArchivedPacket(index: 0, numberOfPackets: 0, nameLength: 0, dataLength: 0)
        let archivedStructLength = sizeof(ArchivedPacket)

        let archivedData = data.subdataWithRange(NSMakeRange(0, archivedStructLength))
        archivedData.getBytes(&archivedPacket)

        let nameRange = NSMakeRange(archivedStructLength, Int(archivedPacket.nameLength))
        let dataRange = NSMakeRange(archivedStructLength + Int(archivedPacket.nameLength), Int(archivedPacket.dataLength))

        let nameData = data.subdataWithRange(nameRange)
        let name = NSString(data: nameData, encoding: NSUTF8StringEncoding) as! String
        let theData = data.subdataWithRange(dataRange)

        let packet = Packet(name: name, index: archivedPacket.index, numberOfPackets: archivedPacket.numberOfPackets, data: theData)

        return packet
    }
}

这篇关于Swift 结构到 NSData 并返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆