J'utilise un tableau d'emballages ASIHTTPRequest (AsyncImageLoader) pour télécharger des images pour les cellules dans un UITableView.ASIHTTPRequest dealloc et problème EXC_BAD_ACCESS
Je vais avoir des problèmes de manipulation de vie ASIHTTPRequests. Si je les libère, je finirai par avoir un EXC_BAD_ACCESS si je continue à défiler de haut en bas pendant qu'ils essaient de charger des images.
Voici à quoi ressemble mon emballage. self.request
a conserver la propriété, targetCell
est la cellule que je veux mettre l'image:
@implementation AsyncImageLoader
- (void)loadImageFromURL:(NSString*)fileName target:(ResultTableViewCell*)targetCell {
// check for cached images, etc
NSURL* url = [NSURL URLWithString:fileName];
[self.request cancel];
self.request = [ASIHTTPRequest requestWithURL:url];
self.request.delegate = self;
}
- (void)startLoading {
[self.request startAsynchronous];
}
- (void)cancel {
[self.request cancel];
self.request = nil;
}
- (void)requestFinished:(ASIHTTPRequest*)requestDone {
// cache image, set cell image...
self.request = nil;
}
- (void)requestFailed:(ASIHTTPRequest*)requestDone {
// handle answer as well
self.request = nil;
}
@end
loadImageFromURL
est appelé à cellForRowAtIndexPath
pour la indexPath.row % 6
e AsyncImageLoader, donc si je continue à défiler vers le haut et vers le bas, il est appelé encore et encore avec le même objet, en annulant les demandes car elles ne sont pas encore terminées.
Mais je finis toujours par avoir un EXC_BAD_ACCESS. Selon la pile d'appel, il se produit dans ASIHTTPRequest de markAsFinished
, appelé par failWithError
, appelé par [self.request cancel]
dans loadImageFromURL:
. La plupart du temps, la requête ASIHTTPRequest était déjà publiée (j'ai ajouté un NSLog dans son dealloc), mais je ne vois pas comment cela est possible car le message ASIHTTPRequest semble se retenir pour ne pas être libéré lors de l'annulation.
Je n'ai aucun EXC_BAD_ACCESS si je supprime self.request = nil
dans les méthodes de délégué, mais comme ASIHTTPRequests continue à être créé sans deallocation, ils ne fonctionnent pas du tout.
Quelqu'un pourrait-il me dire ce que je fais mal?
Vous appelez annuler sur un objet nul, c'est ce que vous faites mal. Comme vous l'avez constaté vous-même, définir la demande sur nil dans les méthodes delegate n'est pas une bonne idée: l'emplacement correct est dans - (void) viewDidUnload –