开发者

IPHONE: memory still allocated after releasing object?

开发者 https://www.devze.com 2022-12-12 18:42 出处:网络
I have a method for drawing an object offscreen to a file, using quartz. The last lines of this method are:

I have a method for drawing an object offscreen to a file, using quartz. The last lines of this method are:

CGRect LayerRect = CGRectMake(mX,mY, wLayer, hLayer);
CGContextDrawImage(objectContext, LayerRect, objectProxy.image.CGImage); // 1

CGRect superRect = CGRectMake(vX, 开发者_如何学CvY, w,h);
CGContextDrawLayerInRect(context, superRect, objectLayer);

CGLayerRelease(objectLayer); // 2
UIImage * myImage = UIGraphicsGetImageFromCurrentImageContext();  
UIGraphicsEndImageContext(); //3
return myImage;

as You see the layer drawn on //1 is released on //2, and the context is released on //3.

So, there's no leak right?

In fact, instruments reports this as having NO LEAKS, but after running this method and returning to the main loop, my application is using 1.38 MB of memory more than before.

Investigating on intruments, on memory allocation tab, I see an entry as

Malloc 1.38 MB
overall bytes = 1.38 MB
#Overall = 1
#alloc = 
Live Bytes = 1.38 MB
#Living = 1
#Transitory = 0

and this entry points to this

CGContextDrawImage(objectContext, LayerRect, objectProxy.image.CGImage); // 1

So, apparently the memory allocated inside the method is still allocated but is not leaking?? How can that be?

How can I get rid of this memory allocation freeing the memory?

thanks in advance!


The image would certainly use some memory. I'm not totally proficient with iPhone programming but an image under OS X is always a copy of what you made the image from. The docs say that the image lives in an autoreleasepool, so depending on how you manage the pools, it could live there for quite some time. You could try putting an autoreleasepool around the call in the calling function (putting it into te function you're quoting above would return an invalid object).

Generally I can say that as soon as autoreleasepools are coming into play, trying to track the releasing of objects will become quite cumbersome (and impossible sometimes ... the idea behind autorelease objects is that the system knows best when to release them (which is something that drives a C++ programmer like me nuts ... but of course Objective C and Cocoa is not made to make me happy :-)))

However, assuming your function above is called drawOffline you should be able to get rid of the memory in image via

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *ret= [self drawOffline];
// do some work using ret (possibly copying it)
[pool release];
// memory should be released and the ret ptr is invalid from this point on.

going a bit further, if you intend to use the ret ptr a bit longer you should retain it to tell the system that it should not delete it even if the autorelease pool releases it.

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *ret= [self drawOffline];
[ret retain]; // prevent ret from being deleted when the pool releases it
// do some work using ret (possibly copying it)
[pool release];
// ret ptr will continue to live until you release it.

// more stuff

[ret release]; // image behind ret being freed 

As said, generally with autorelease objects you don`t worry about their lifetime, but if you intend to keep them longer (especially storing it in an object member for later use) you need to retain/release it yourself, because otherwise the system could pull it right under your feet.

This [link][1] describes memory management under OS X but also applies to the iphone.

[1]: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html link


apparently there's no solution for that, until Apple fix this.

0

精彩评论

暂无评论...
验证码 换一张
取 消