2

I got a memory leaking problem from a very simple function. Here is my code:

  -(void) drawPuzzle
 {

      gameView.image=nil;     

      UIGraphicsBeginImageContext(gameView.frame.size);


      [gameView.image  drawInRect:CGRectMake(0,
                                             0, 
                                             gameView.frame.size.width,
                                             gameView.frame.size.height)];



       CGContextRef con=UIGraphicsGetCurrentContext();
       CGContextMoveToPoint(con, 20,0);
       CGContextAddLineToPoint(con,20, gameView.frame.size.height);
       CGContextStrokePath(con);


       UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
       UIGraphicsEndImageContext();
       [gameView setImage:newImage];


  }

The instruments report as below:

Event Type    RefCt      Responsible Caller

Malloc        1          +[UIImage imageWithCGImage: scale: orientation:] 
Autorelease              +[UIImage imageWithCGImage: scale: orientation:] 
Retain        2          -[UIImageView setImage:]
Release       1          -[NSAutoreleasePool drain]       
Sergey Kuryanov
  • 6,114
  • 30
  • 52
Lynn
  • 31
  • 6
  • do you release gameView.image ? (Assuming it is retained by setImage) – giorashc Apr 02 '12 at 13:03
  • How? [gameView.image release] or gameView.image=nil? I don't know why I need to [gameView.image release] but I did gameView.image=nil before [gameView release]. – Lynn Apr 02 '12 at 13:19
  • Thanks, after I add gameView.image=nil;[gameView.image release]; [gameView release]; to my dealloc function memory leaking disappeared. But I still don't understand why I need to do [gameView.image release] since I never retain or alloc gameView.image. And this is not my first time to set an image to UIImageView.image I never need to release **.image thing before? – Lynn Apr 02 '12 at 13:28
  • when you synthesize a retainable property its set method retains the object for you. so when you call setImage then [gameView.image retain] is called for you. And thats why you need to release gameView.image at dealloc – giorashc Apr 02 '12 at 13:49
  • I still don't understand. gameView is an object of UIImageView. image is a retainable property of UIImageView. But why it's my responsibility to release the retainable property of UIImageView. [image release] should be included in the dealloc method of UIImageView. I'm really confused now. – Lynn Apr 02 '12 at 17:02
  • From some reason I assumed gameView is an instance of a custom object. If so where do you release gameView ? (If you do release gameView in a dealloc method did you make sure that dealloc is indeed being called ?) – giorashc Apr 02 '12 at 19:32
  • gameView is an instance of UIImageView and it's an IBOutlet connected to XIB. I did put gameView=nil in ViewDidUnload and [gameView release] in dealloc. I also released a lot of other IBOutlet object in the dealloc method but only got the memory leaking from gameView setImage:. Actually I used UIImageView all the time but this is the first time to setImage using UIGraphicsGetImageFromCurrentImageContext(). Did this cause the problem? – Lynn Apr 02 '12 at 20:16
  • Look at this post : http://stackoverflow.com/questions/5121120/uigraphicsgetimagefromcurrentimagecontext-memory-leak-pdf-previews. Tell me if it helped you. – giorashc Apr 02 '12 at 20:23
  • Ok, now I removed the whole function and add one line to me code [gameView setImage:[UIImage imageNamed:@"100Correct.png"]]; I also removed gameView.image=nil;[gameView.image release]; only keep [gameView release]; . There is no memory leaking at all. So I'm quite sure [gameView release] is called indeed. Do you have any idea why UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [gameView setImage:newImage]; has memory leaking? – Lynn Apr 02 '12 at 20:30
  • I think there is a memory leak in the release of a UIImageView that contains a UIImage with the autorelease property. – Lynn Apr 02 '12 at 20:32
  • I read this post yesterday but today I read it again and understand it better. It helps . Especially this sentence: "I think there is a memory leak in the release of a UIImageView that contains a UIImage with the autorelease property." I guess autorelease property is ok but autorelease property from UIGraphicsGetImageFromCurrentImageContext(); might not be ok. I'll try to write my own MyUIImageView class derived from UIImageView to solve the problem. Even it's not elegant it makes me feel better to release the image property by myself. Thank you very much for your great help. – Lynn Apr 02 '12 at 20:39
  • Unfortunately I have no idea what goes inside UIGraphicsGetImageFromCurrentImageContext – giorashc Apr 02 '12 at 20:41
  • I found this : http://stackoverflow.com/questions/4644912/iphone-uiimageview-setimage-leaks It mentioned "Yes, UIImageView setImage does leak! Actually, leaks CGImage, not UIImage" . I think what he said is correct. – Lynn Apr 02 '12 at 20:54

1 Answers1

-2

setImage: method retained your newImage. To avoid memory leak you need to release newImage after setImage

   UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
   UIGraphicsEndImageContext();
   [gameView setImage:newImage];
   [newImage release];
Sergey Kuryanov
  • 6,114
  • 30
  • 52
  • This doesn't make sense. Even setImage: retained newImage it shouldn't be my responsibility to release it. And I tried and code crashed. – Lynn Apr 02 '12 at 13:16
  • The caller is not responsible for releasing the result of a function with `Get` semantics. – Jonathan Grynspan Apr 02 '12 at 13:26