Hi,
I'm using an array of ASIHTTPRequest wrappers (AsyncImageLoader) to download images for cells in a UITableView.
I'm having problems handling ASIHTTPRequests lifetime. If I release them, I end up having a EXC_BAD_ACCESS if I keep scrolling up and down while they try to load images.
Here's what my wrapper looks like. self.request
has retain property, targetCell
is the cell I want to put the image in:
@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
is called in cellForRowAtIndexPath
for the indexPath.row % 6
th AsyncImageLoader, so if I keep scrolling up and down it is called again and again with the same object, cancelling requests as they aren't over yet.
But I always end up having a EXC_BAD_ACCESS. According to the call stack it happens in ASIHTTPRequest's markAsFinished
, called by failWithError
, called by [self.request cancel]
in loadImageFromURL:
. Most of the time the ASIHTTPRequest was already released (I added a NSLog in it's dealloc), but I don't see how this is possible as the ASIHTTPRequest seems to throw retains so it is not freed while cancelling.
I don't have any EXC_BAD_ACCESS if I remove self.request = nil
in the delegate methods, but as ASIHTTPRequests keep being created without deallocation, they end up not working at all.
Could someone tell me what am I doing wrong?