Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to release the UIImage?

I use the following code to draw a subimage

UIImage* subIm = getSubImage( large, rect );
[subIm drawInRect:self.bounds];

where getSubImage is defined as follows

    UIImage* getSubImage(UIImage* uim, CGRect rc){
      CGImageRef imref  = CGImageCreateWithImageInRect(uim.CGImage, rc); 
      UIImage*   sub = [UIImage imageWithCGImage:imref];
      CGImageRelease(imref);
        NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
      return sub;
   }//getSubImage

Is the code correct?

Is it safe to "CGImageRelease" imref?

Has sub "CGImageRetained" imref?

Should I release subIm (I get an error if I do)?

Is subIm contained in the autorelease-pool, and , if so, how do I know this?

In general, can one check if an object is contained in the autorelease pool (for debugging purpose)?

like image 534
ragnarius Avatar asked Dec 28 '10 13:12

ragnarius


1 Answers

Do Not Call -retainCount

The number returned by retain count is the absolute retain count of the object. There may be many retains in play that you have no control over as they are implementation details of the frameworks. There are always better ways to validate your code's memory management.

Retain counts should only be considered as deltas; if you cause a retain count to increase, you must cause it to be decreased.

Given:

UIImage* getSubImage(UIImage* uim, CGRect rc){
  CGImageRef imref  = CGImageCreateWithImageInRect(uim.CGImage, rc); 
  UIImage*   sub = [UIImage imageWithCGImage:imref];
  CGImageRelease(imref);
    NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
  return sub;
}//getSubImage

imageWithCGImage: returns an autoreleased object. The retain count is irrelevant in that imageWithCGImage: might internally be doing any number of things -- caching, etc. -- that might influence the retain count.

get* is an odd pattern to use in Cocoa programming. You just don't see that much.

I'd suggest something like:

- (UIImage *) subImage: (UIImage *) anImage inRect: (CGRect) aRect
{
      CGImageRef imageRef  = CGImageCreateWithImageInRect(anImage.CGImage, aRect); 
      UIImage*   subImage = [UIImage imageWithCGImage: imageRef];
      CGImageRelease(imageRef);
      return subImage;
}
like image 146
bbum Avatar answered Oct 03 '22 04:10

bbum