NSMutableData емкость при изменении длины

Что произойдет с NSMutableData, инициализированным с емкостью 1 МБ, если я добавлю в него 10 МБ данных, а затем установлю длину на ноль? Уменьшает ли это емкость до первоначального значения или оставляет ее как есть (на данный момент 10Mb)?

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

2 ответа

Решение

Состояние документации:

setLength: расширяет или усекает изменяемый объект данных до заданной длины.

- (void)setLength:(NSUInteger)length

Параметры length Новая длина для получателя.

Обсуждение Если объект изменяемых данных расширен, дополнительные байты заполняются нулями.

Доступность Доступно в Mac OS X v10.0 и более поздних версиях. См. Также - IncreaseLengthBy: связанный пример кода LSMSmartCategorizer объявлен в NSData.h


Так что я бы пошел на "усеченные" до 0 размера.
Но чтобы убедиться, что вы можете сделать небольшой тест и проверить трассировку кучи в приборе.

Apple не гарантирует какого-либо особого поведения в данном случае, однако, насколько мне известно, NSMutableData будет только "расти" в объеме, но никогда не будет сокращаться. Это означает, что если вы создаете объект NSMutableData, добавляете к нему 10 МБ данных, а затем устанавливаете его длину равным 0, на самом деле внутреннему пространству памяти будет выделено 10 МБ, он просто сообщит 0 для своего свойства длины. Это аналогичное поведение, которое вы можете отслеживать с помощью NSMutableArray, и такое же поведение, которое вы можете отслеживать в других языках программирования (например, большинство стандартных объектов Java ведут себя таким образом).

Причина этого проста: выделение памяти - дорогостоящая операция. Не очень дорого, но обычно это не O(1). Только изменение длины является очень быстрой операцией O (1), так как нужно только изменить переменную экземпляра. Если вы уменьшите длину, а NSMutableArray сократит свое внутреннее хранилище, ему придется выполнить перераспределение, и в следующий раз, когда вы добавите данные, ему придется снова выполнить перераспределение. Это означает, что если вы хотите использовать как можно меньше памяти, вам не следует возвращать длину к нулю, а вместо этого создать новый NSMutableData и освободить старый. Только это гарантирует минимальное использование памяти. Недостатком является то, что в следующий раз, когда вы добавите в него память, это будет намного более дорогой операцией, поскольку необходимо перераспределение. Это обычный обмен ЦП против памяти. Чем меньше памяти вы позволяете использовать фрагменту кода, тем больше памяти он обычно потребляет; с другой стороны, чем больше памяти вы позволяете использовать фрагменту кода, тем больше процессорного времени он может сэкономить.

Поскольку у Mac обычно достаточно памяти, он не окупает изменяемый объект данных, чтобы перераспределить его внутреннюю память, по крайней мере, если бы это сэкономило только пару МБ. С другой стороны, он может действительно перераспределиться, если вы уменьшите 500 МБ объекта данных до нуля. И поскольку никакое поведение не гарантировано, NSMutableData может вести себя совсем по-другому на iOS, потому что на устройствах iOS память является гораздо более ограниченным ресурсом.

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