4

J'ai ce gros problème avec la gestion de la mémoire.UIScrollView avec de nombreux UIImageViews - Gestion de la mémoire

Le problème:
J'ai un UIScrollView, j'ai un tableau avec 24 chemins vers Images et je veux leur montrer dans le UIScrollView avec la pagination activée.

Toutes les images ont une taille de 1024x748 (résolution de paysage iPad avec barre d'état) et le type de fichier est jpg ou png.

J'utilise chargement paresseux juste pour ne pas dépasser la mémoire lorsque le viewDidLoad. Et je vais avec l'exemple de chargement paresseux d'Apple avec le PageControl. Bien que j'utilise UIImageViews au lieu de UIViews.

Donc, mon problème est que lorsque je fais défiler jusqu'à la troisième image, je veux retirer la première image du UIScrollView et libérer sa mémoire. Parce que plus je défile, plus la mémoire est drainante. Quand je pagine dans le UIScrollView et qu'une nouvelle image est chargée et ajoutée, environ 5000kb de plus de mémoire est utilisée, et quand je prends le unloadPage: (voir ci-dessous) rien n'est libéré. Suis-je juste "mal fait"?

Comment libérer et supprimer correctement UIImageViews?

(je charge les UIImages avec initWithContentsOfFile:)

Voici mon code:

@interface SlideViewController : UIViewControllerExtended <UIScrollViewDelegate> { 

    ScrollViewController *slider; 
    IconView *currentChapter; 
    NSMutableArray *chapters; 
    NSMutableArray *views; 
    UIImageView *controller; 

} 

La fonction de charge paresseux:

- (void) loadImageToScrollView:(NSInteger)chapter withPage:(NSInteger)page { 


    if (page < 0) return; 
    if (page >= chapterCount) return; 

    if([views objectAtIndex:page] != [NSNull null]) return; 

    NSMutableArray *all = [[currentChapter getImages] copy]; 

    if(!([[all objectAtIndex:page] rangeOfString:@".mp4"].length > 0)) { 
     controller = [views objectAtIndex:page]; 

     if((NSNull *)controller == [NSNull null]) { 

      NSArray *paths = [[all objectAtIndex:page] componentsSeparatedByString:@"."]; 

      NSString *name = [[NSString alloc] initWithString:[paths objectAtIndex:0]]; 
      NSString *ending = [[NSString alloc] initWithString:[paths objectAtIndex:1]]; 

      NSString *file = [[NSString alloc] initWithFormat:@"%@", [[NSBundle mainBundle] pathForResource:name ofType:ending]]; 

      UIImageView *tempImage = [[UIImageView alloc] initWithFrame:CGRectMake(page * 1024, 0, 1024, 768)]; 
      UIImage *img = nil; 
      img = [[UIImage alloc] initWithContentsOfFile:file]; 

      [tempImage setImage:img]; 
      [tempImage setTag:page]; 

      self.controller = tempImage; 
      [tempImage release]; 

      [slider addSubview:controller]; 
      [views replaceObjectAtIndex:page withObject:controller]; 

      [name release]; 
      [ending release]; 
      [file release]; 
     } 

    } 

    [all release]; 
} 

La vue unload méthode (qui ne semble pas fonctionner):

- (void) unloadPage: (int) page { 
    if(page < 0) return; 
    if(page >= chapterCount) return; 
    if((NSNull *)[views objectAtIndex:page] != [NSNull null]) { 
     UIImageView *viewToDelete = [views objectAtIndex:page]; 

     [viewToDelete removeFromSuperview]; 

     [views replaceObjectAtIndex:page withObject:[NSNull null]]; 
    } 
} 

Répondre

7

Le problème est résolu en regardant la session vidéo #104 à WWDC2010. Ce qui peut être trouvé sur le Apple Developer site.

Donc, si vous avez des problèmes avec les fuites de mémoire lors du chargement de grandes images, vérifiez-le. C'est vraiment, vraiment utile.

+4

Le nom complet de la session est "Session 104 - Conception d'applications avec des vues de défilement" – Bastian

0

VSScrollview bien que je sois en retard mais pour les autres utilisateurs, j'ai créé une classe, VSScrollview, qui réutilise ses vues comme UITableView réutilise sa cellule. Son utilisation est simple. Parcourez le fichier readme du lien