English 中文(简体)
iphone memory deallocation issue with scrollview with image inside
原标题:

I m having trouble deallocating a UISCrollView that contains images. There s something wrong with my code, but I cannot understand where.

this is a snippet of my code. It basically create a loops adding a uiscrollview with an image and removing. If you run the code with instruments, no memory will be freed. I also add some check for the retainCount, with no luck at all..

here s the code

- (void)loadView {
 [super loadView];
 CGRect theRect = CGRectMake(0, 0, 320, 480);
 UIView *view = [[UIView alloc] initWithFrame:theRect];
 [view setBackgroundColor:[UIColor purpleColor] ];
 self.view = view;
 [view release];

 UIView *pippo = [[UIView alloc] initWithFrame:theRect];
 [pippo setBackgroundColor:[UIColor redColor]];
 [self.view addSubview:pippo];
 [pippo release];

 [self performSelector:@selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}



-(void)scrollAdd:(id)o {
 CGRect theRect = CGRectMake(0, 0, 320, 480);
 int numero = 1;
 scroll = [[UIScrollView alloc] initWithFrame:theRect];
 [scroll setContentSize:CGSizeMake( 320*numero,1)];
 [scroll setScrollEnabled:YES];

 UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"koala1b" ofType:@"jpg"]];
 int dd = [img retainCount];
 UIImageView *v2 = [[UIImageView alloc] initWithFrame:theRect];
 [v2 setImage:img];
 [scroll addSubview:v2];
 dd = [v2 retainCount];
 [v2 release];
 dd = [v2 retainCount];
 dd = [img retainCount];
 [self.view addSubview:scroll];
 [img release];
 dd = [img retainCount];

 [self performSelector:@selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}

-(void)scrollRemove:(id)o {
 int dd = [scroll retainCount];
 UIImageView *theV = [[scroll subviews] objectAtIndex:0];
 dd = [theV retainCount];
 [scroll removeFromSuperview];
 dd = [theV retainCount];
 [theV release];
 dd = [theV retainCount];
 dd = [scroll retainCount];
 scroll = nil;
 [self performSelector:@selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}
最佳回答

The issue is that you are releasing img when you shouldn t (which is probably being masked by the view hierarchy never being released), and you aren t releasing scroll when you should.

-(void)scrollAdd:(id)o {
 CGRect theRect = CGRectMake(0, 0, 320, 480);
 int numero = 1;
 scroll = [[UIScrollView alloc] initWithFrame:theRect];
 [scroll setContentSize:CGSizeMake( 320*numero,1)];
 [scroll setScrollEnabled:YES];

 UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"koala1b" ofType:@"jpg"]];
 int dd = [img retainCount];
 UIImageView *v2 = [[UIImageView alloc] initWithFrame:theRect];
 [v2 setImage:img];
 [scroll addSubview:v2];
 [v2 release];
 [self.view addSubview:scroll];
 [img release];
 dd = [img retainCount];

 [self performSelector:@selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}

This should be:

-(void)scrollAdd:(id)o {
  CGRect theRect = CGRectMake(0, 0, 320, 480);
  int numero = 1;
  scroll = [[UIScrollView alloc] initWithFrame:theRect];
  [scroll setContentSize:CGSizeMake( 320*numero,1)];
  [scroll setScrollEnabled:YES];

  UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"koala1b" ofType:@"jpg"]];
  UIImageView *v2 = [[UIImageView alloc] initWithFrame:theRect];
  [v2 setImage:img];
  [scroll addSubview:v2];
  [v2 release];
  [self.view addSubview:scroll];

  [self performSelector:@selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}

Of course if you do this you need to also make a slight change in your view removal path:

-(void)scrollRemove:(id)o {
  [scroll removeFromSuperview];
  [scroll release];
  scroll = nil;

 [self performSelector:@selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}
问题回答

I ve basically reached the same conclusions as @Louis, but also made some comments within the code as to what I removed and why.

- (void)loadView {
 [super loadView];
 CGRect theRect = CGRectMake(0, 0, 320, 480);
 UIView *view = [[UIView alloc] initWithFrame:theRect];
 [view setBackgroundColor:[UIColor purpleColor] ];
 self.view = view;
 [view release];

 UIView *pippo = [[UIView alloc] initWithFrame:theRect];
 [pippo setBackgroundColor:[UIColor redColor]];
 [self.view addSubview:pippo];
 [pippo release];

 [self performSelector:@selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}



-(void)scrollAdd:(id)o {
     CGRect theRect = CGRectMake(0, 0, 320, 480);
     int numero = 1;
     scroll = [[UIScrollView alloc] initWithFrame:theRect];
     [scroll setContentSize:CGSizeMake( 320*numero,1)];
     [scroll setScrollEnabled:YES];

    // img is already autoreleased, you re releasing again down below
    // --- UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"koala1b" ofType:@"jpg"]];
    UIImageView *v2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"koala1b.jpg"]];
    v2.frame = theRect;
    //--- [v2 setImage:img];
    [scroll addSubview:v2];
    [v2 release];
    [self.view addSubview:scroll];
    // NO !; img is autoreleased from imageWithContentsOfFile
    //--- [img release];

    [self performSelector:@selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}

-(void)scrollRemove:(id)o {
     //--- UIImageView *theV = [[scroll subviews] objectAtIndex:0];
     [scroll removeFromSuperview];
     // you don t own theV because you didn t create it here, or send it a retain. So NO release
     // it also appears that you think you re responsible for releasing or cleaning up
     // a view s subviews.  NO. Just call [scroll removeFromSuperview] and let scroll view
     // clean it s own resources.
     //--- [theV release];
     [scroll release];
     scroll = nil;
     [self performSelector:@selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}




相关问题
Using QCView and iSight to capture image

I have a QCView that loads a Quartz file which gives you iSights feedback (basically like a QTCaptureView) Everything displays fine The button simply takes a snapshot using the following simple ...

Taking picture with QTCaptureView

Is it possible to simply take a picture and save it somewhere using a QTCaptureView and Apple s built-in iSight? I ve seen lots of tutorials on recording video but none on simply taking a picture. Any ...

Transform rectangular image into trapezoid

In .NET how can I transform an image into a trapezoid. The Matrix class supports rotation, shear, etc, but I can t see a trapezoidal transformation. I m using the usual System.Drawing.* API, but I m ...

Rotate image through Y-axis on web page

What are my options for rotating an image on a web page through the Y-axis? I m not sure if I even have the terminology right. Is this called a rotate or a transform. Most of the searches that I ve ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

Editing a xaml icons or images

Is it possible to edit a xaml icons or images in the expression design or using other tools? Is it possible to import a xaml images (that e.g you have exported) in the expression designer for editing?...

Convert from 32-BPP to 8-BPP Indexed (C#)

I need to take a full color JPG Image and remap it s colors to a Indexed palette. The palette will consist of specific colors populated from a database. I need to map each color of the image to it s "...

热门标签