CGImage 中的内存泄漏

发布于 2024-08-23 05:56:00 字数 1139 浏览 4 评论 0原文

我有内存泄漏,我只是不知道如何解决。

这是泄漏代码:

[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;

我修改存储在 Data 中的像素信息,然后使用此方法从 Data 创建一个 UIImage (作为 unsigned char 数组)

xcode 仪器告诉我这里存在泄漏:

CGImageRef new_img = CGBitmapContextCreateImage(context);

而这里:

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

虽然我把它们都释放了:(有人能告诉我如何解决这个问题吗?

提前谢谢^-^

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

This is 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 ^-^

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空气里的味道 2024-08-30 05:56:00

几乎可以肯定,您未能在代码中的其他位置释放 newImg 。也许您没有在 -dealloc 中释放它。如果这是真的,那么 Instruments 将标记分配内存的代码行。它不知道你什么时候应该或不应该释放;它只知道内存何时被分配以及何时被释放。您需要审核您的代码以了解如何管理此 ivar。

也就是说,您直接访问您的 ivars,这很糟糕。这是 ObjC 内存问题的第一大原因。使用属性和访问器(initdealloc 中除外),这些问题往往会消失。 (并转换为 ARC。很少有理由再使用手动保留计数,特别是在 iOS 上。尽管如此,即使使用 ARC,我还是建议使用访问器而不是直接接触你的 ivars。)

另外:不要调用你的属性 newImg。前缀new在ObjC中有特殊的含义(它意味着返回的对象应该有一个有效的+1保留计数)。这可能会导致您出现内存问题和误报警告。它的名称应类似于 convertedImagenextImage

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.

凹づ凸ル 2024-08-30 05:56:00

编辑:原帖似乎没有帮助,所以删除并重新发布。

试试这个:

//[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);

已经测试过了,我这边没有泄漏。

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.

鱼窥荷 2024-08-30 05:56:00

CGBitmapContextCreate 不会释放您提供的数据。要么给它 NULL(在这种情况下,上下文将管理自己的后备内存),要么在释放上下文后自行释放它。

编辑:这里是相关的文档。

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.

想念有你 2024-08-30 05:56:00

在我看来,您没有发布 conversionImage 尝试

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

这一行替换这一

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

在代码中用

行。如果我理解正确(基于对问题的评论),您可以像这样声明 newImg 属性:

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

在这种情况下,该属性的合成设置器将保留将分配给它的任何对象。并在值发生变化时释放它。
所以你不负责发布它,你应该删除这一行:

[newImg release];

我想,你能做的最好的事情就是阅读 高级内存管理编程指南。它不太长,但它提供了 iOS 内存管理中使用的主要约定的完整概述。

由于您还使用 CoreFoundation 对象/函数,请考虑 Core Foundation 内存管理编程指南

我希望它会有所帮助:)

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 :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文