Search code examples
objective-ccocoa-touchmemory-managementnsmutabledata

Using the bytes of an NSMutableData instance while allowing it to be autoreleased


I've been using

NSMutableData* mutableData = [NSMutableData dataWithLength: someLength];
void* bitmapData = [mutableData mutableBytes];
CGContextRef context = CGBitmapContextCreate(bitmapData,...);
// ...use context
CGContextRelease(context);

I have an autorelease pool in place, but when looking at this in Instruments, mutableData doesn't seem to be deallocated.
I thought of using alloc/init like below, but I'm not sure if sending release would purge bitmapData as well.

NSMutableData* mutableData = [[NSMutableData alloc] initWithLength: someLength];
void* bitmapData = [mutableData mutableBytes];
[mutableData release];
//...

What's the proper way of using NSMutableData here?

I thought using NSMutableData instead of malloc() and free() would be convenient because it'll be autoreleased. but now I'm not sure if that's true.


Solution

  • When you say mutableData doesn't seem to be deallocated, do you mean at the point of CGContextRelease(), or do you mean it never deallocates and it leaks every time you run this?

    In your first example, you would not expect mutableData to deallocate until the autorelease pool drains (generally at the end of the event loop), because you used -dataWithLength:. In your second example, it's undefined whether mutableData would be released. The call to -mutableBytes might apply a retain and autorelease to ensure the pointer is valid for the rest of the event loop (this is pretty common with these kinds of methods), but the docs don't say, so your second example is undefined behavior if you use bitmapData later.

    Now if mutableData leaks, then you're likely over-retaining it somewhere else.