I can add bytes to a NSMutableData instance easily by using the appendData
method, however I do not see any similar method for removing data? Am I overlooking something, or do I need to create a new object and copy over only the bytes I need?

- 68,471
- 58
- 283
- 421

- 17,317
- 32
- 140
- 246
4 Answers
Please see the documentation of the following method:
- (void)replaceBytesInRange:(NSRange)range
withBytes:(const void *)replacementBytes
length:(NSUInteger)replacementLength
Apple says the following:
If the length of range is not equal to
replacementLength
, the receiver is resized to accommodate the new bytes. Any bytes past range in the receiver are shifted to accommodate the new bytes. You can therefore passNULL
forreplacementBytes
and0
forreplacementLength
to delete bytes in the receiver in the range range. You can also replace a range (which might be zero-length) with more bytes than the length of the range, which has the effect of insertion (or “replace some and insert more”).
To remove 10 byte from the end, use:
data.length = data.length - 10;
It could also be done via replaceBytesInRange
, but it's in fact much faster, because the bytes are not really removed. Instead only the internal size variable is changed and NSMutableData
will behave as if the bytes were removed. IOW, this is a O(1) operation (that means it will always take equally long to perform, regardless of how many bytes you remove), and it is very fast.
To remove 10 byte from front, use:
[data replaceBytesInRange:NSMakeRange(0, 10) withBytes:NULL length:0];
To remove 10 bytes in the middle (e.g. after 20 bytes), use:
[data replaceBytesInRange:NSMakeRange(20, 10) withBytes:NULL length:0];
replaceBytesInRange
is a O(n) operation, though. The time required to perform the operation depends on how many bytes the data object has and where you remove them, as all bytes right to the remove location must be shifted to the left. It is still pretty fast and only limited by the throughput of your computer's memory (RAM). If you have 10 MB of data and you remove 1 MB from front, 9 MB are copied to fill the gap of the just removed MB. So the speed of the operation depends on how fast your system can move 9 MB of RAM from one address to another one (which on my system takes 0.2 milliseconds for 9 MB).

- 125,244
- 33
- 244
- 253
-
This is a great answer, although it's derivative of an answer that has way less upvotes and is now irrelevant. Might you revise it to make it a standalone answer? +1 – Dan Rosenstark Feb 12 '12 at 23:01
-
1@Yar:Sure, why not. I removed the reference to the other answer. – Mecki Feb 13 '12 at 19:41
-
Somehow I got back to this answer today, was looking for "You can also replace a range (which might be zero-length) with more bytes than the length of the range, which has the effect of insertion (or “replace some and insert more”)." Tangential but relevant. Thanks! – Dan Rosenstark Feb 14 '12 at 22:41
-
I used these methods to remove two bytes in front, and one byte at the end. Very useful - probably is memory intensive on large data sets. But it works very well... – Ashu Joshi Mar 03 '12 at 15:04
-
but what about when i want to remove data from the front? – Peter Lapisu Feb 04 '15 at 09:40
-
@PeterLapisu It's in my reply. The second code sample removes 10 bytes from front. – Mecki Feb 04 '15 at 10:32
-
yup, but it basically doesn't shrink the NSData like the setLength... i would like to offset the front pointer, so the whole structure gets smaller – Peter Lapisu Feb 05 '15 at 10:07
-
@PeterLapisu It's not defined how it shrinks the data, that's implementation specific (it may copy bytes around, it may as well just change the pointer) and Apple is free to change the current behavior whenever they want w/o even letting anyone know. This method is the only way NSMutableData offers for removing data in front, if you don't like it, write your own data wrapper class and make it work the way you want. – Mecki Feb 05 '15 at 13:19
Since NSMutableData is toll-free bridged with CFMutableDataRef, you can use the CFDataDeleteBytes() function:
NSMutableData *data = ...
CFDataDeleteBytes((CFMutableDataRef)data, CFRangeMake(3, 4));

- 289
- 1
- 2
-
3Be careful. Down this path lies performance woes. If you are editing relatively few times or working with a small bit of data, no big deal. Anything larger or frequent or performance sensitive, consider using an optimized data structure of some type. – bbum Feb 27 '10 at 02:33
-
Thanks, this worked great. How do you know that NSMutable data is 'toll-free bridged' with CFMutableDataRef? I do not see any mention of this in the NSMutableData docs? – Kyle Feb 27 '10 at 11:47
-
If you look at the "Overview" section of the NSMutableData docs http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSMutableData_Class/Reference/NSMutableData.html you'll see it mentioned in the second paragraph – RJ. Mar 01 '10 at 17:50
-
1Why using CoreFoundation, if you can use the NSMutableData method replaceBytesInRange, which according to documentation removes the bytes in range, if the replacement byte pointer is NULL and the replacement length is also 0? – Mecki Aug 03 '10 at 21:59
-
1While this solution works, I think Mecki's is the cleaner and should be marked the accepted. +1 to Mecki, but no ding here foe a find 2nd best solution. (it would be interesting to know if, under the covers, one solution uses the other! :) – Olie Dec 10 '10 at 16:35
-
@bbum does your comment apply to the other (accepted) answer as well? – Dan Rosenstark Feb 13 '12 at 21:04
-
Yes. Any time you start mucking with a data in ways that may change the overall length, you can easily end up copying lots and lots of bytes all about. – bbum Feb 13 '12 at 21:39
If the data you want to remove is at the end, you can use
[NSMutableDataInstance setLength:[NSMutableDataInstance length] - n];
or with the obj-c 2.0 syntax
NSMutableDataInstance.length -= n;
for anything more complicated than that I'd recommend manipulating the raw data.

- 4,925
- 2
- 29
- 39
I see that this thread has the answer, but nevertheless this could be valuable add. To remove all bytes from NSMuttableData, you can create new Data and copy it to original:
[myData setData:[NSData dataWithBytes:NULL length:0]];
This works great.

- 309
- 2
- 16