Search code examples
iosuitableviewnsurlconnectionobjective-c-blocks

Ios table cell image download by NSURLConnection sendAsynchronousRequest causes crash on table cell delete


I am calling a block for table cell image download.

[self downloadImageWithURL:aa completionBlock:^(BOOL succeeded, UIImage *image) {
            if (succeeded) {

            cell.imageView.image = image;


            ((DatabaseHelper *) [upcoming objectAtIndex:indexPath.row]).image = image;
        }
        }];



- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void     (^)(BOOL succeeded, UIImage *image))completionBlock
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                           if ( !error )
                           {
                               UIImage *image = [[UIImage alloc] initWithData:data];
                               completionBlock(YES,image);
                           } else{
                               completionBlock(NO,nil);
                           }
                       }];
}

and it is working perfectly fine... but the problem is that, once for any cell the block is called, if i delete that cell before the completion of AsynchronousRequest, the app crashes. so how can I remove the call from NSoperation queue when i delete the cell.

project log


Solution

  • Since I believe your code is crashing here: [upcoming objectAtIndex:indexPath.row]. A quick fix would be to check whether your array is available or not, like this:

    [self downloadImageWithURL:aa completionBlock:^(BOOL succeeded, UIImage *image) {
            if (succeeded && upcoming && [upcoming lenght] > indexPath.row) {
    
            cell.imageView.image = image;
    
    
            ((DatabaseHelper *) [upcoming objectAtIndex:indexPath.row]).image = image;
        }
        }];
    

    A more clean solution would be to implement a controller, that stores all your requests. When you have this, its easy to cancel them. You should not do this inside your UITableViewController or UITableViewCell.