如果需要返回它,如何释放CGImageRef?

时间:2013-06-10 02:46:17

标签: ios macos cocoa core-graphics

我有一种方法可以调整CGImageRef的大小并返回CGImageRef。问题是最后几行,我需要以某种方式释放,但之后返回。有任何想法吗?感谢

 -(CGImageRef)resizeImage:(CGImageRef *)anImage width:(CGFloat)width height:(CGFloat)height
{

    CGImageRef imageRef = *anImage;

    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);

    if (alphaInfo == kCGImageAlphaNone)
        alphaInfo = kCGImageAlphaNoneSkipLast;


    CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo);

    CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);

    CGImageRef ref = CGBitmapContextCreateImage(bitmap);

    CGContextRelease(bitmap);
    CGImageRelease(ref); //issue here

    return ref;

}

2 个答案:

答案 0 :(得分:5)

Cocoa内存管理命名策略指出,您拥有一个对象,该对象是从名称以 alloc copy new 。
Clang静态分析仪也遵守这一规则。

请注意,Core Foundation的约定略有不同。详细信息可在Apple's Advanced Memory Management Programming Guide中找到。

我修改了上面的方法以符合命名约定。在传递anImage时我也删除了星号,因为CGImageRef已经是指针。 (或者这是故意的吗?) 请注意,您拥有所返回的CGImage,并且稍后必须CGImageRelease

-(CGImageRef)newResizedImageWithImage:(CGImageRef)anImage width:(CGFloat)width height:(CGFloat)height
{
    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(anImage);
    if (alphaInfo == kCGImageAlphaNone)
    {
        alphaInfo = kCGImageAlphaNoneSkipLast;
    }
    CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(anImage), 4 * width, CGImageGetColorSpace(anImage), alphaInfo);
    CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), anImage);
    CGImageRef image = CGBitmapContextCreateImage(bitmap);
    CGContextRelease(bitmap);
    return image;
}

答案 1 :(得分:0)

你也可以操作指针anImage(删除星号后,如@weichsel建议的那样)并返回void

但是,你应该阅读你的代码并思考问题:

  • 谁拥有anImage? (显然不是你的方法,因为它既不保留也不复制它)
  • 当您使用方法时,如果所有者发布了该怎么办? (或代码运行时可能发生的其他事情)
  • 方法完成后会发生什么? (又名:你记得在调用代码中发布它吗?)

所以,我强烈建议你不要混合使用CoreFoundation,它可以使用函数,指针和“经典”数据结构,也可以使用Foundation,它可以处理对象和消息。 如果你想在CF结构上运行,你应该编写一个C函数来完成它。如果要对Foundation对象进行操作,则应使用方法编写(子)类。如果你想混合两者或提供一个桥梁,你应该确切地知道你在做什么,并编写包装器类,它们公开一个Foundation-API并在内部处理所有的CF-stuff(因此在发布结构时留给你)。