NSMutableData удалить байты? - PullRequest
       22

NSMutableData удалить байты?

26 голосов
/ 27 февраля 2010

Я могу легко добавить байты к экземпляру NSMutableData с помощью метода appendData, однако я не вижу подобного метода удаления данных? Я что-то пропускаю или мне нужно создать новый объект и скопировать только те байты, которые мне нужны?

Ответы [ 4 ]

72 голосов
/ 04 августа 2010

Пожалуйста, смотрите документацию следующего метода:

- (void)replaceBytesInRange:(NSRange)range withBytes:(const void *)replacementBytes length:(NSUInteger)replacementLength

Apple четко говорит следующее:

Если длина диапазона не равна замена длины, приемник изменен для размещения новых байтов. Любые байты за пределами диапазона в приемнике сдвинуты, чтобы приспособить новый байт. Поэтому вы можете передать NULL для replaceBytes и 0 для Замена длины для удаления байтов в приемник в диапазоне дальности. Вы также может заменить диапазон (который может быть нулевой длины) с большим количеством байтов, чем длина диапазона, который имеет эффект вставки (или «заменить некоторые и вставь больше »).

Чтобы удалить 10 байт с конца, используйте:

[data setLength:[data length] - 10];

Это также можно сделать с помощью replaceBytesInRange, но на самом деле это гораздо быстрее, потому что байты на самом деле не удаляются. Вместо этого изменяется только внутренняя переменная размера, и NSMutableData будет вести себя так, как если бы байты были удалены. Итак, это операция O (1) (это означает, что она всегда будет выполняться одинаково долго, независимо от того, сколько байтов вы удалите), и она очень быстрая.

Чтобы удалить 10 байт с фронта, используйте:

[data replaceBytesInRange:NSMakeRange(0, 10) withBytes:NULL length:0];

Чтобы удалить 10 байтов в середине (например, после 20 байтов), используйте:

[data replaceBytesInRange:NSMakeRange(20, 10) withBytes:NULL length:0];

replaceBytesInRange - это операция O (n). Это означает, что независимо от того, сколько времени потребуется для удаления 100 байт, для удаления 200 байт потребуется вдвое больше времени и так далее. Это все еще довольно быстро и ограничено только пропускной способностью памяти вашего компьютера (RAM). Если у вас есть 10 МБ данных, и вы удаляете 1 МБ спереди, 9 МБ копируются, чтобы заполнить пробел только что удаленного МБ. Таким образом, скорость операции зависит от того, насколько быстро ваша система сможет переместить 9 МБ ОЗУ с одного адреса на другой. И это обычно достаточно быстро, если только вы не имеете дело с объектами NSMutableData, содержащими сотни МБ.

3 голосов
/ 27 февраля 2010

Поскольку NSMutableData является бесплатным для моста через CFMutableDataRef, вы можете использовать функцию CFDataDeleteBytes ():

NSMutableData *data = ...
CFDataDeleteBytes((CFMutableDataRef)data, CFRangeMake(3, 4));
1 голос
/ 27 февраля 2010

Если данные, которые вы хотите удалить, находятся в конце, вы можете использовать

[NSMutableDataInstance setLength:[NSMutableDataInstance length] - n];

или с синтаксисом obj-c 2.0

NSMutableDataInstance.length -= n;

для чего-то более сложного, чем я бы порекомендовал манипулировать необработанными данными.

0 голосов
/ 31 марта 2013

Я вижу, что у этой ветки есть ответ, но тем не менее это может быть ценным дополнением.Чтобы удалить все байты из NSMuttableData, вы можете создать новые данные и скопировать их в оригинал:

[myData setData:[NSData dataWithBytes:NULL length:0]];

Это прекрасно работает.

...