How to release CGImageRef if required to return it?

I have a way to resize CGImageRef and return CGImageRef . The problem is in the last few lines, where I need to somehow release, but return it after. Any ideas? Thanks

  -(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; } 
+4
source share
2 answers

Cocoa's memory management naming policy states that you own an object created from methods that start with alloc, copy, or new.
These rules are also respected by the Clan Static Analyzer.

Note that there are slightly different conventions for the Core Foundation. See the Apple Extended Memory Management Programming Guide for more details.

I modified your above method to fit these naming conventions. I also removed the asterisk when passing in anImage , since CGImageRef already a pointer. (Or was it on purpose?).
Note that you have returned CGImage and it should CGImageRelease later.

 -(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; } 
+5
source

You can also work with the anImage pointer (after removing an asterisk, such as the one suggested by @weichsel) and returning void .

However, you should read your code and think about the questions:

  • Who owns anImage ? (obviously not your method, since it does not save or copy it).
  • What happens if it is released by the owner during your method? (or other things that can happen to it during your code)
  • What happens after your method completes? (otherwise: you remember to release it in the calling code).

So, I highly recommend that you not mix CoreFoundation, which works with functions, pointers, and "classic" data structures, and Foundation, which works with objects and messages. If you want to work with CF structures, you must write a C function that does this. If you want to work with Foundation objects, you must write (sub) classes using methods. If you want to mix both or provide a bridge, you must know exactly what you are doing and write wrapper classes that expose the Foundation API and process all the CF material inside themselves (thus leaving it to you when structures are released).

0
source

Source: https://habr.com/ru/post/1485348/


All Articles