Question

What happens with NSMutableData initialized with 1Mb capacity if I put 10Mb of data into it and then set length to zero? Does it shrink capacity back to initial value or leaves it as is (10Mb at the moment)?

So basically I need to shrink whole data object to initial capacity and I don't need data inside, but I don't like the idea to re-create object for that, is there any way to achieve that?

Was it helpful?

Solution

The documentation state :

setLength: Extends or truncates a mutable data object to a given length.

- (void)setLength:(NSUInteger)length

Parameters length The new length for the receiver.

Discussion If the mutable data object is extended, the additional bytes are filled with zeros.

Availability Available in Mac OS X v10.0 and later. See Also – increaseLengthBy: Related Sample Code LSMSmartCategorizer Declared In NSData.h


So I would go for "truncates" to a 0 size.
But to be sure you can make a little test and check the heap trace in instrument.

OTHER TIPS

Apple does not guarantee any specific behavior here, however as far as my experience goes, a NSMutableData will only "grow" in capacity, it will never shrink. That means, if you create a NSMutableData object, add 10 MB of data to it and then set its length to 0, it will in fact still internally have a storage space of 10 MB allocated, it will just report 0 for its length property. This is similar behavior you can monitor with NSMutableArray and it's the same behavior you can monitor in other programming languages (e.g. most Java standard objects behave that way).

The reason for that is simple: Memory allocation is an expensive operation. Not horribly expensive, but it's usually not O(1). Only changing the length is a very fast O(1) operation, since it only has to alter an instance variable. If you decrease the length and NSMutableArray shrinks its internal storage, it had to perform a reallocation and next time you add data, it has to perform a reallocation again. That means if you want to use as little memory as possible, you should not set the length back to zero, but instead create a new NSMutableData and release the old one. Only that will guarantee you smallest memory usage possible. The downside is that next time you add memory to it, it will be a much more expensive operation since a reallocation is necessary. It's the usual CPU vs memory trade off. The less memory you allow a piece of code to use, the more memory it will usually consume; on the other hand, the more memory you allow a piece of code to use, the more CPU time it can save.

Since Macs have usually plenty of memory, it does not pay off for a mutable data object to reallocate its internal memory, at least not if this would only save a couple of MBs. On the other hand, it might really reallocate if you shrink a 500 MB data object back to zero. And as no behavior is guaranteed, NSMutableData might behave quite differently on iOS because on iOS devices memory is a much more restricted resource.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top