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

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

4 ответа

Решение

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

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

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

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

Чтобы удалить 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, содержащими сотни МБ.

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

NSMutableData *data = ...
CFDataDeleteBytes((CFMutableDataRef)data, CFRangeMake(3, 4));

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

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

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

NSMutableDataInstance.length -= n;

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

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

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

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

Другие вопросы по тегам