2011-10-12 4 views
2

J'ai un projet iOS dans lequel j'utilise ARC dans mes propres classes, mais j'ai désactivé ARC dans d'autres bibliothèques comme ASIHTTPRequest.ASIHTTPDemande de fuites de mémoire

Je reçois d'énormes fuites de mémoire en utilisant le code ci-dessous pour récupérer une image à partir d'un serveur Web:

-(void)buildPhotoView { 

self.photoLibView.hidden = NO; 

NSString *assetPathStr = [self.cellData objectForKey:@"AssetThumbPath"]; 

// get the thumbnail image of the ocPHOTOALBUM from the server and populate the UIImageViews 
NSURL *imageURL = [NSURL URLWithString:assetPathStr]; 

__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:imageURL]; 
__unsafe_unretained ASIHTTPRequest *weakRequest = request; 
[weakRequest setCompletionBlock:^{ 

    // put image into imageView when request complete 
    NSData *responseData = [weakRequest responseData]; 
    UIImage *photoAlbumImage = [[UIImage alloc] initWithData:responseData]; 
    self.photo1ImageView.image = photoAlbumImage; 
}]; 
[weakRequest setFailedBlock:^{ 
    NSError *error = [request error]; 
    NSLog(@"error geting file: %@", error); 
}]; 
[weakRequest startAsynchronous]; 

}

J'ai modifié le code exemple à partir de la page de code exemple ASIHTTPRequest à éliminer les avertissements du compilateur dans Xcode.

Comment puis-je me débarrasser de ces fuites de mémoire? Je semble seulement les avoir en utilisant des blocs.

+0

Est-ce que l'instanciation de 'photoAlbumImage' avec un objet autoreleased réduit la taille de la fuite? c'est-à-dire 'photoAlbumImage = [UIImage imageWithData: responseData];' – FluffulousChimp

+0

Vous ne pouvez pas utiliser autoRelease lors de l'utilisation du comptage automatique des références. Je ne reçois pas de fuites de mémoire lorsque j'utilise ASIHTTPRequest SANS utiliser de blocs, mais dans ce cas je dois le faire parce que je fais plusieurs demandes d'images, chacune d'entre elles entrant dans une UIImageView différente dans la tableCell. Avec les blocs, je peux inclure un bloc d'achèvement dans la requête qui place l'image dans le UIImageView correct lorsque la requête est terminée. – Alpinista

Répondre

7

Vous référencez la mauvaise variable de demande dans le bloc d'achèvement. Vous devez référencer request dans le bloc (c'est pourquoi vous le déclarez avec l'identificateur __block). En fait, vous ne devriez pas avoir besoin de déclarer weakRequest.

Si vous souhaitez que la requête soit conservée en mémoire, stockez-la dans un @property (retain) dans votre classe (celle avec la méthode buildPhotoView peut-être).

+0

J'ai déclaré weakRequest parce que Xcode a affiché un avertissement: Comptage automatique des références Problème: Capturer fortement 'request' dans ce bloc est susceptible d'entraîner un cycle de rétention. J'ai le même nombre d'erreurs quand je ne déclare pas weakRequest. – Alpinista

+2

Oh. Dans ce cas, préfixe 'request' avec' __unsafe_unretained' ainsi que '__block'. – darvids0n

+0

FWIW J'ai essayé d'utiliser: '__block __unsafe_unretained ASIHTTPRequest * request' - qui a fonctionné en mode débogage, mais j'ai eu des plantages en production! - Le problème est que lorsque vous activez l'optimisation de l'objectif c, ce code se bloque une fois que vous essayez d'accéder à 'request', donc NE PAS utiliser à la fois' __unsafe_unretained __block' s'il s'agit de la seule référence à l'objet request! :) – herbert