开发者

Memory leak in CGImage

开发者 https://www.devze.com 2022-12-21 14:10 出处:网络
I\'ve got a memory leak i just don\'t know how to solve. This i开发者_StackOverflow中文版s the leaking code:

I've got a memory leak i just don't know how to solve.

This i开发者_StackOverflow中文版s the leaking code:

[newImg release];
CGColorSpaceRef d_colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =  CGBitmapContextCreate(Data, width, 
                                              height, 
                                              8, 4*width, 
                                              d_colorSpace, 
                                              kCGImageAlphaNoneSkipFirst);
UIGraphicsPushContext(context);
CGImageRef new_img = CGBitmapContextCreateImage(context);
UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];
CGImageRelease(new_img);
CGContextRelease(context);
CGColorSpaceRelease(d_colorSpace);
newImg = convertedImage;

I modify pixel information stored in Data, then with this method i create a UIImage back from the Data (which is as unsigned char array)

The xcode instruments tells me that there are leaks in here:

CGImageRef new_img = CGBitmapContextCreateImage(context);

And here:

UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];

though i release both of them :( Can somebody tell me how to solve this?

Thanks in advance ^-^


Almost certainly you are failing to release newImg somewhere else in your code. Perhaps you are not releasing it in -dealloc. If this is true, then Instruments will flag the line of code that allocated the memory. It doesn't know when you should or shouldn't have released; it just knows when the memory was allocated and when it was freed. You'll need to audit your code for how you manage this ivar.

That said, you are directly accessing your ivars, which is bad. This is the #1 cause of memory problems in ObjC. Use properties and accessors (except in init and dealloc), and these problems will tend to go away. (And convert to ARC. There is very seldom a reason to use manual retain counting anymore, particularly on iOS. Still, even with ARC, I recommend using accessors and not touching your ivars directly.)

Also: do not call your property newImg. The prefix new has a special meaning in ObjC (it means that the returned object should have a effective +1 retain count). This can cause you memory problems and false-positive warnings. It should have a name like convertedImage or nextImage.


Edit: Original post did not seem to help, so deleting and re-posting.

Try this instead:

//[newImg release]; DELETE THIS LINE
CGColorSpaceRef d_colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =  CGBitmapContextCreate(Data, width, 
                                              height, 
                                              8, 4*width, 
                                              d_colorSpace, 
                                              kCGImageAlphaNoneSkipFirst);
UIGraphicsPushContext(context);
CGImageRef new_img = CGBitmapContextCreateImage(context);

newImg = [UIImage imageWithCGIImage:new_img];

CGImageRelease(new_img);
CGContextRelease(context);
CGColorSpaceRelease(d_colorSpace);

Have tested this and it does not leak on my end.


CGBitmapContextCreate won't release the Data you give it. Either give it NULL (in which case the context will manage its own backing memory) or release it yourself after you release the context.

EDIT: here is the relevant documentation.


Seems to me that you don't release convertedImage Try to replace this line

UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];

with this one

UIImage * convertedImage = [[[UIImage alloc] initWithCGImage:
                             new_img] autorelease];

in your code.

And if I understand you correctly (based on comments to question), you declare newImg property like so:

@property (nonatomic, retain) UIImage* newImg; //or something like that

In this case the synthesized setter for this property will retain any object that will be assigned to it. And release it when the value will change. So you are not responsible for releasing it and you should remove this line:

[newImg release];

I guess, the best thing you can do is to read Advanced Memory Management Programming Guide. It isn't too long and yet it provides a complete overview of main conventions used in iOS memory management.

And since you also work with CoreFoundation objects/functions, consider the Memory Management Programming Guide for Core Foundation.

I hope it will help :)

0

精彩评论

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

关注公众号