iphone内存释放问题与scrollview与图像里面

时间:2009-11-12 11:51:14

标签: iphone image memory-management memory-leaks uiscrollview

我无法释放包含图像的UISCrollView。 我的代码出了问题,但我无法理解。

这是我的代码片段。它基本上创建一个循环添加uiscrollview与图像和删除。 如果使用仪器运行代码,则不会释放任何内存。 我还为retainCount添加了一些检查,没有运气......

这是代码

- (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];
}

2 个答案:

答案 0 :(得分:1)

问题在于,当你不应该发布时,你正在释放img(可能被视图层次结构掩盖了永远不会被释放),并且你没有在你应该发布滚动时。

-(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];
}

这应该是:

-(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];
}

当然,如果您这样做,您还需要在视图删除路径中稍作更改:

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

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

答案 1 :(得分:1)

我基本上得出了与@Louis相同的结论,但也在代码中对我删除的内容和原因做了一些评论。

- (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];
}