当前位置: 首页 > 面试题库 >

Swift结构到NSData并返回

魏鸿哲
2023-03-14
问题内容

我有一个包含一个结构的结构,NSObject并且我想序列化为一个NSData对象:

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)

如何最好地将Packet序列化为NSData,以及如何最好地对其进行反序列化?

使用

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

只给了我名称和数据的指针。我正在探索NSKeyedArchiver,但是随后我必须将Packet作为对象,并且我希望将其保留为结构。

干杯

尼克


问题答案:

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

  1. 我的结构的制造encode()decode()功能
  2. 更改Int为,Int64以便Int在32位和64位平台上具有相同的大小
  3. 具有一个中间结构(ArchivedPacket),该结构没有String或Data,而只有Int64

这是我的代码,非常感谢您的反馈,尤其是在没有那么麻烦的方法的情况下:

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
    }
}


 类似资料:
  • 问题内容: 怎么转换成?如果应该这样做 那怎么算呢? 以及如何转换为? 问题答案: 缓冲区长度为frameCapacity * bytesPerFrame。以下是可以在NSData和AVAudioPCMBuffer之间进行转换的函数。

  • 问题内容: 我正在尝试快速进行简单的DNS查找。到目前为止,这是我拥有的代码: 此时,“地址” NSArray中的每个元素都是一个CFDataRef对象,该对象包装了一个sockaddr结构。 由于CFDataRef可以免费连接到NSData,因此可以像这样循环遍历它们: 到目前为止,一切都很好(我认为)。当我在单元测试中运行时,这会打印出有效的外观数据。这是我被卡住的地方。为了我的一生,我不知道

  • 问题内容: 我正在尝试保存到,然后在Swift中读回新的内容。要转换到我使用下面的代码: 如何将(即)转换回新的? 问题答案: 假设图像的比例为1。 在Swift 4.2中,将以下代码用于get Data()。

  • Swift 4提供了一个灵活的构建块,它使用构造作为结构体。 通过利用这些结构,可以定义构造方法和属性。 与C语言和Objective C不同 结构体不需要实现文件和接口。 结构体允许创建单个文件并将接口自动扩展到其他块。 在结构体中,通过返回旧值的副本来复制变量值并在后续代码中传递,以便不能更改这些值。 语法 定义结构体 例如,假设必须访问包含三个科目分数的学生记录,并计算出三个科目的总分数。

  • Swift 结构体是构建代码所用的一种通用且灵活的构造体。 我们可以为结构体定义属性(常量、变量)和添加方法,从而扩展结构体的功能。 与 C 和 Objective C 不同的是: 结构体不需要包含实现文件和接口。 结构体允许我们创建一个单一文件,且系统会自动生成面向其它代码的外部接口。 结构体总是通过被复制的方式在代码中传递,因此它的值是不可修改的。 语法 我们通过关键字 struct 来定义结

  • 主要内容:?:运算符决策结构要求程序员指定程序要评估或测试的一个或多个条件,在条件被确定为真时要执行的语句,以及如果条件被认定是假的(可选的),则执行其他语句。 以下是大多数编程语言中的典型决策结构如下所示 - Swift 4提供以下类型的决策声明。单击以下链接查看其详细信息。 编号 语句 描述 1 if语句 语句由一个布尔表达式后跟一个或多个语句组成。 2 if…else语句 语句后面可以跟一个可选的语句,语句在布