Reputation: 41685
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.
Upvotes: 2
Views: 1467
Reputation: 3009
Asking an instance of NSMutableData for its mutableBytes simply returns a pointer to the existing (already allocated) buffer that it manages for you. It does not have any effect on the memory from a management perspective.
So, in your first example, the fact that mutableData doesn't appear to be deallocated when looking at it in Instruments could be related to the autorelease pool environment at the time. Does the code using mutableData in that way have an NSAutoreleasePool in place? Do you see warnings in the console like "autorelease called with no pool in place; just leaking"? If so, you just need to wrap the code in:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// bitmap drawing code here
[pool drain];
In the second sample, you could use alloc/init on the NSMutableData instance, but you would need to release it after you were done using the pointer you get from mutableBytes. The pointer will be pointing to deallocated (freed) memory after you call release, and accessing it will result in the dreaded EXC_BAD_ACCESS.
Also, using malloc/free would probably be my first choice here, since you get to be very explicit about how and when the memory is allocated and freed. NSMutableData + autorelease isn't really buying you anything except some overhead, if you aren't using the object for anything else.
Upvotes: 0
Reputation: 299355
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.
Upvotes: 1