CGImageRef 内存泄漏

发布于 2024-10-09 19:06:45 字数 853 浏览 3 评论 0原文

我在使用返回 CGImageRef 的自定义方法时遇到内存泄漏。我无法正确释放“cgImage”,因为我必须归还它。我该怎么办?

- (CGImageRef)rectRoundedImageRef:(CGRect)rect radius:(int)radius
{
    CGSize contextSize = CGSizeMake(rect.size.width, rect.size.height);     
    CGFloat imageScale = (CGFloat)1.0;
    CGFloat width = contextSize.width;
    CGFloat height = contextSize.height;        
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, width * imageScale, height * imageScale, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    // Draw ...
    // Get your image
    CGImageRef cgImage = CGBitmapContextCreateImage(context);       
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    //CGImageRelease(cgImage); //If I release cgImage the app crashes.
    return cgImage;     
}

I'm having a memory leak when using this custom method which returns a CGImageRef. I can't release "cgImage" properly because I have to return it. What chould I do ?

- (CGImageRef)rectRoundedImageRef:(CGRect)rect radius:(int)radius
{
    CGSize contextSize = CGSizeMake(rect.size.width, rect.size.height);     
    CGFloat imageScale = (CGFloat)1.0;
    CGFloat width = contextSize.width;
    CGFloat height = contextSize.height;        
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, width * imageScale, height * imageScale, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    // Draw ...
    // Get your image
    CGImageRef cgImage = CGBitmapContextCreateImage(context);       
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    //CGImageRelease(cgImage); //If I release cgImage the app crashes.
    return cgImage;     
}

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

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

发布评论

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

评论(4

只等公子 2024-10-16 19:06:45

cgImage 归您的方法所有,您需要返回它并让调用者负责通过 CFRelease 释放它。

您还可以返回包装在 UIImage 实例中的 CGImage,如下所示:

UIImage *image = [UIImage imageWithCGImage:cgImage];
CFRelease(cgImage); //cgImage is retained by the UIImage above
return image;

cgImage is owned by your method, you need to return it and give responsibility to the caller to release it through CFRelease.

You can also return the CGImage wrapped inside a UIImage instance, like this:

UIImage *image = [UIImage imageWithCGImage:cgImage];
CFRelease(cgImage); //cgImage is retained by the UIImage above
return image;
无语# 2024-10-16 19:06:45

这是 Core Foundation 对象的普遍问题,因为 CF 中没有自动释放池。在我看来,您有两种选择来解决问题:

  1. 将方法重命名为 -newRectRoundedImageRef:radius: 之类的名称,以告诉调用者他拥有返回对象的所有权并负责释放它。
  2. 将 CGImageRef 包装在自动释放的 UIImage 对象中并返回该对象 ([UIImage imageWithCGImage:])。这可能就是我会做的。

This is a general problem with Core Foundation objects because there is no autorelease pool in CF. As I see it, you have two options to solve the problem:

  1. Rename the method to something like -newRectRoundedImageRef:radius: to tell the caller that he takes ownership of the returned object and responsible for releasing it.
  2. Wrap the CGImageRef in an autoreleased UIImage object and return that ([UIImage imageWithCGImage:]). That's probably what I would do.
寂寞笑我太脆弱 2024-10-16 19:06:45

您可以自动释放与 Core Foundation 兼容的对象。它只是看起来有点奇怪。 :)

GC 安全的方式是这样的:

CGImageRef image = ...;
if (image) {
    image = (CGImageRef)[[(id)image retain] autorelease];
    CGImageRelease(image);
}

在 iOS 上安全但在 Mac 上不再安全的快捷方式是这样的:

CGImageRef image = ...;
if (image) {
    image = (CGImageRef)[(id)image autorelease];
}

任一者都将图像放置在自动释放池中并防止泄漏。

You can autorelease a Core Foundation-compatible object. it just looks a bit wonky. :)

The GC-safe way is like so:

CGImageRef image = ...;
if (image) {
    image = (CGImageRef)[[(id)image retain] autorelease];
    CGImageRelease(image);
}

The shortcut, which is safe on iOS but no longer safe on the Mac, is this:

CGImageRef image = ...;
if (image) {
    image = (CGImageRef)[(id)image autorelease];
}

Either one will place the image in an autorelease pool and prevent a leak.

一杆小烟枪 2024-10-16 19:06:45

正如建议的那样,我们使用了:

CGImageRelease(imageRef);

但我们仍然遇到内存泄漏。
我们的解决方案是用一个

@autoreleasepool {}

块包装代码,这解决了我们的问题。

As suggested, we used:

CGImageRelease(imageRef);

but we still got an memory leak.
our solution was to wrap code with an

@autoreleasepool {}

block and that solve our problem.

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