NSMutableData, обработать полученные данные и удалить из буфера начала / повторного использования? - PullRequest
2 голосов
/ 10 октября 2011

Это может быть легко.Я использую GCDAsyncSocket для получения переменного количества байтов, представляющих отдельные фрагменты данных с сервера, которые появляются в объекте NSMutableData.

Если бы данные были словами, они могли бы выглядеть следующим образом:

ChunkChunkChunkChu

nkChunkChunkChunkCh

Таким образом, после обработки трех фрагментов, частичный фрагмент "Чу" остается и должен быть сохранен, чтобы следующая партияданные могут составить конкуренцию этому фрагменту.

В настоящий момент процесс обработки выглядит следующим образом:

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, поэтому я ожидаю, что накладные расходы на создание / освобождение уменьшатся.

1 Ответ

5 голосов
/ 10 октября 2011

Я думаю, что Меки ошибся в сообщении, на которое вы ссылались.Чем больше данных вы удалите, тем быстрее будет быстрее , поскольку нужно будет скопировать меньше байтов.Кроме того, поскольку вы просто перемещаете данные из конца в начало и изменяете длину, это должно быть быстрее, чем создание нового буфера, поскольку вам нужно только скопировать байты, а не создавать буфер, копировать байты и уничтожатьстарый буфер.

Исходя из вашего примера, первый набор данных - ChunkChunkChunkChu.Это длина 18 байт, и вы хотите сохранить последние 3. Используя replaceBytesInRange:withBytes:length:, операция выглядит следующим образом:

  1. Используйте полные куски.После этого length равно 18, а numLeft равно 3.
  2. Позвоните [buffer replaceBytesInRange:(NSRange){0,length-numLeft} withBytes:nil length:0];
    a.Скопируйте 3 байта из позиции 15 в позицию 0.
    b.Установите длину 3.
  3. Получите больше данных.

При создании нового буфера операция выглядит следующим образом.

  1. Использование полных блоков,После этого length равно 18, а numLeft равно 3.
  2. Выделите новый буфер.
  3. Добавить оставшиеся байты в новый буфер.
    a.Скопируйте 3 байта из позиции 15 старого буфера в позицию 0 нового буфера.
    b.Длина нового буфера теперь равна 3.
  4. Освободить старый буфер.
  5. Получите больше данных.

Как видите, операция точно такая же, за исключением того, что у второго есть издержки на создание нового буфера и уничтожение старого.

...