2 votes

libérer NSData dans NSManagedObject

J'utilise un modèle de données pour stocker deux objets : Vidéo, Images. La vidéo ne contient que des attributs de type chaîne et les images ont 2 attributs de type "données binaires".

Au départ, les 2 attributs de données binaires se trouvaient dans l'objet vidéo. Mais toutes les vidéos sont chargées pendant l'initialisation de UITableView. Pour 400 vidéos les données binaires représentent 20 Mo, alors imaginez avec 4000 vidéos...

Maintenant avec 2 objets le chargement de UITableView fonctionne bien. Je charge les données binaires quand c'est nécessaire dans la méthode : tableView:cellForRowAtIndexPath

Mais maintenant, plus je fais défiler la liste, plus la mémoire grandit :(

regardez ma méthode :

- (UITableViewCell *)tableView:(UITableView *)myTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"videoCell";
    Video *theVideo = (Video *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
    VideoCellViewController *cell = (VideoCellViewController *)[myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"VideoCellView" owner:self options:nil];
        cell = editingTableViewCell;
        self.editingTableViewCell = nil;
    }
    cell.video = theVideo;
    return cell;
}

Et la méthode setvideo dans VideoCellViewController

- (void)setVideo:(Video *)newVideo {
    if (newVideo != video) {
        [video release];
        video = [newVideo retain];
    }
    NSData *imageData = [video.allImages valueForKey:@"thumbnailImage"];
    UIImage *uiImage = [[UIImage alloc] initWithData:imageData];
    smallImage.image = uiImage;
    nameLabel.text = video.displayName;
    [uiImage release];
}

Même sans définir le smallImage, j'ai des problèmes de mémoire. Si je charge l'objet image, il n'est jamais libéré.

J'ai essayé plusieurs solutions pour libérer la mémoire sans succès...( didTurnIntoFault, release, CFRelease...) Dans l'outil de performance, je peux voir mes données binaires comme CFData.

J'utilise beaucoup l'échantillon iPhoneCoreDataRecipes et PhotoLocations.

J'ai besoin d'aide pour nettoyer ma mémoire ;)

Merci

Samuel

1voto

slf Points 15327

Il y a manifestement quelque chose qui se passe dans la logique de création des cellules de votre tableau. Regardons un exemple typique de cellForRow le premier gestionnaire de délégué

static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
// do stuff with cell
return cell;

Ici, nous voyons que nous sommes

  • essayer d'obtenir une cellule réutilisable
  • si cela échoue (nil) créez-en un nouveau et passer l'id réutilisable au ctor
  • puis faire quelque chose avec la cellule (nouvelle ou existante) et la retourner

Si vous ne saisissez pas la cellule pour la réutiliser dans la vue tableau, vous obtiendrez toujours une cellule "nulle" renvoyée par la déqueue, d'où la nécessité de créer de nouvelles cellules à chaque fois. De ce fait, la mémoire continuera de croître au fur et à mesure que vous vous déplacerez, mais restera relativement stable en cas d'inactivité.

EDIT :

En supposant que votre cellule est en bon état, vous devez déterminer si ce sont les données vidéo ou les données d'image qui fuient. Ce qui est smallImage ? Et êtes-vous sûr que vous ne voulez pas tout faire uniquement lorsque la vidéo est nouvelle ?

- (void)setVideo:(Video *)newVideo {
    if (newVideo != video) {
        [video release];
        video = [newVideo retain];
        NSData *imageData = [video.allImages valueForKey:@"thumbnailImage"];
        UIImage *uiImage = [[UIImage alloc] initWithData:imageData];
        smallImage.image = uiImage;
        nameLabel.text = video.displayName;
        [uiImage release];
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X