我有一个
protobuf v2 in Swift,我试图附加到另一个原型.这是我正在尝试的:
let attachment = getAttachment(id: 987) //From cloud database var protosData = NSMutableData(data: attachment) items.forEach { //Some struct array of values guard let proto = try? MyProtoBuf.Builder() .setEpochMillis($0.date.epochMilliseconds) .setValue($0.value) .build() else { return } protosData.appendData(proto.data()) } saveAttachment(protosData) //Store to cloud
看来我正在破坏数据,因为我读回来时会收到这个错误:
malloc: *** mach_vm_map(size=2749415424) Failed (error code=3) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug
也许是我的回读值是不正确的,这是我正在做的从存储读取附加数据:
extension GeneratedMessageProtocol { static func getStreamData(data: NSData) -> [Self] { var messages = [Self]() do { let inStream = NSInputStream(data:data) inStream.open() defer { inStream.close() } while inStream.hasBytesAvailable { var sizeBuffer: [UInt8] = [0,0] inStream.read(&sizeBuffer,maxLength: sizeBuffer.count) let data = NSData(bytes: sizeBuffer,length: sizeBuffer.count) let messageSize = data.uint32.littleEndian var buffer = Array<UInt8>(count: Int(messageSize),repeatedValue: 0) inStream.read(&buffer,maxLength: Int(messageSize)) let messageData = NSData(bytes: buffer,length:Int(messageSize)) messages.append(try self.parseFromData(messageData)) } } catch { } return messages } } extension NSData { var uint32: UInt32 { get { var number: UInt32 = 0 self.getBytes(&number,length: sizeof(UInt32)) return number } } }
这里是我的protobuf信息:
Syntax = "proto2"; message MyProtoBuf { optional uint64 epochMillis = 1; optional uint32 value = 2; }
将数据附加到现有protobuf的正确方法是什么,而不是逐个解析数组项,附加原型,然后将整个数组转换回字节?
你的阅读部分没问题.在链接原始对象时,您将缺少分隔符.首先计算并添加分隔符到流,然后再添加原始对象.然后为每个原型对象做.
let attachment = getAttachment(id: 987) //From cloud database var arr: [UInt32] = [UInt32(attachment.length)] //Assuming attachment is NSData type let delimiter = NSData(bytes: arr,length: arr.count * sizeof(UInt32)) let protosData = NSMutableData(data: delimiter) protosData.appendData(attachment) items.forEach { //Some struct array of values guard let proto = try? MyProtoBuf.Builder() .setEpochMillis($0.date.epochMilliseconds) .setValue($0.value) .build() else { return } var array: [UInt32] = [UInt32(proto.data().length)] let delimit = NSData(bytes: array,length: arr.count * sizeof(UInt32)) protosData.appendData(delimit) protosData.appendData(proto.data()) } saveAttachment(protosData) //Store to cloud