проблема освобождения памяти iphone с прокруткой с изображением внутри - PullRequest
0 голосов
/ 12 ноября 2009

У меня проблемы с освобождением 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 ]

1 голос
/ 12 ноября 2009

Я в основном пришел к тем же выводам, что и @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];
}
1 голос
/ 12 ноября 2009

Проблема в том, что вы выпускаете 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];
}
...