2009-11-12 2 views
0

У меня возникли проблемы с освобождением UISCrollView, содержащего изображения. Что-то не так с моим кодом, но я не могу понять, где.проблема освобождения памяти iphone с scrollview с изображением внутри

это фрагмент моего кода. Он в основном создает петли, добавляя 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]; 
} 

ответ

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

Я в основном достигли те же выводы, что и @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]; 
} 
+0

Спасибо, ваше решение не увеличивает использование памяти! Это было действительно полезно –

Смежные вопросы