2

这可能是一件容易的事。我正在使用 GCDAsyncSocket 从服务器接收可变数量的字节,这些字节表示出现在 NSMutableData 对象中的离散数据块。

如果数据是单词,它可能看起来像这样:

ChunkChunkChunkChu

nkChunkChunkChunkCh

因此,在处理了三个块之后,部分块“Chu”仍然存在并且必须保留,以便下一批数据可以与该块竞争。

现在的处理流程是这样的:

receive data, appending to myBuffer
process contents of buffer up to last complete chunk
create new myBuffer with partial fragment of remaining data chunk at end of buffer
back to the start

这很好用,但我不确定它是否是最有效的方法。我看到 NSMutableData 有一个 replaceBytesInRange ,我可以用它来从缓冲区的开头删除已处理的字节数,但据报道它是一个缓慢的操作

关于最好的方法有什么建议吗?如果它有所作为,我正在使用 ARC,所以我希望减少创建/释放的开销。

4

1 回答 1

5

我认为 Mecki 在您链接到的帖子中弄错了。您删除的数据越多,速度就越快,因为需要复制的字节更少。此外,由于您只是将数据从末尾移动到开头并更改长度,因此它应该比创建新缓冲区更快,因为您只需复制字节而不是创建缓冲区、复制字节和销毁旧缓冲区。

使用您的示例,第一组数据是ChunkChunkChunkChu. 这是 18 个字节长,您希望保留最后 3 个字节。使用replaceBytesInRange:withBytes:length:,操作如下所示:

  1. 使用完整的块。在此之后,length是 18 和numLeft3。
  2. [buffer replaceBytesInRange:(NSRange){0,length-numLeft} withBytes:nil length:0];
    一个。从位置 15 复制 3 个字节到位置 0。
    b.将长度设置为 3。
  3. 接收更多数据。

通过创建一个新的缓冲区,操作看起来像这样。

  1. 使用完整的块。在此之后,length是 18 和numLeft3。
  2. 分配一个新的缓冲区。
  3. 将剩余字节追加到新缓冲区。
    一个。从旧缓冲区的位置 15 复制 3 个字节到新缓冲区的位置 0。
    湾。新缓冲区的长度现在为 3。
  4. 释放旧缓冲区。
  5. 接收更多数据。

如您所见,操作完全相同,只是第二个具有创建新缓冲区和销毁旧缓冲区的开销。

于 2011-10-09T21:05:26.577 回答