1

I am using NSOperationQueue for caching images in background. Here is the code below:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"CellIdentifier";
UITableViewCell *cell;
cell = [self.mUpcomEventsTable dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}

cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

UIImageView *imgView;
UILabel *lblEventName;
UILabel *lblDate;
UILabel *lblTime;
if(self.mEventNameArr != NULL)
{
NSString *imageUrlString = [NSString stringWithFormat:@"%@", [self.mEventImageArr objectAtIndex:indexPath.row]];
UIImage *cachedImage = [self.imageCache objectForKey:imageUrlString];
    NSLog(@"cache:%@", self.imageCache);

    imgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 80, 90)];

    lblEventName = [[UILabel alloc]initWithFrame:CGRectMake(90, 10, 200, 30)];
    lblEventName.text = [self.mEventNameArr objectAtIndex: indexPath.row];
    lblEventName.font = [UIFont fontWithName:@"Helvetica-Bold" size:18];
    lblDate = [[UILabel alloc]initWithFrame:CGRectMake(90, 50, 100, 30)];
    lblDate.text = [self.mEventDateArr objectAtIndex:indexPath.row];
    lblTime = [[UILabel alloc]initWithFrame:CGRectMake(190, 50, 100, 30)];
    lblTime.text = [self.mEventTimeArr objectAtIndex:indexPath.row];

    strEventName = lblEventName.text;
    strEventDate = lblDate.text;
    strEventTime = lblTime.text;

if (cachedImage)
{
    imgView.image = cachedImage;
}
else
{
    // you'll want to initialize the image with some blank image as a placeholder

    imgView.image = [UIImage imageNamed:@"Placeholder.png"];

    // now download in the image in the background
    NSLog(@"queue:%@",self.imageDownloadingQueue);
    [self.imageDownloadingQueue addOperationWithBlock:^{

        NSURL *imageUrl   = [NSURL URLWithString:imageUrlString];
        NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
        UIImage *image    = nil;
        if (imageData)
            image = [UIImage imageWithData:imageData];

        if (image)
        {

            [self.imageCache setObject:image forKey:imageUrlString];

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{

                UITableViewCell *updateCell = [tableView cellForRowAtIndexPath:indexPath];
                if (updateCell)
                    imgView.image = cachedImage;
            }];
        }
    }];
}
}
else cell.textLabel.text = @"No event";
[cell addSubview:imgView];
[cell addSubview:lblEventName];
[cell addSubview:lblDate];
[cell addSubview:lblTime];
return cell;
}

It is not going in this line [self.imageDownloadingQueue addOperationWithBlock:^{ it go outside from this. Why so, please help for above. Took idea from here link.

Community
  • 1
  • 1

1 Answers1

0

There are a lot of disadvantage of using NSOperationQueue. One of them is your image will flick when every time you scroll the UITableView.

I'd suggest you to use this AsyncImageView. I've used it and it work wonders. To call this API:

ASyncImage *img_EventImag = alloc with frame;
NSURL *url = yourPhotoPath;
[img_EventImage loadImageFromURL:photoPath];
[self.view addSubView:img_EventImage]; // In your case you'll add in your TableViewCell.

It's same as using UIImageView. Easy and it does most of the things for you. AsyncImageView includes both a simple category on UIImageView for loading and displaying images asynchronously on iOS so that they do not lock up the UI, and a UIImageView subclass for more advanced features. AsyncImageView works with URLs so it can be used with either local or remote files.

Loaded/downloaded images are cached in memory and are automatically cleaned up in the event of a memory warning. The AsyncImageView operates independently of the UIImage cache, but by default any images located in the root of the application bundle will be stored in the UIImage cache instead, avoiding any duplication of cached images.

The library can also be used to load and cache images independently of a UIImageView as it provides direct access to the underlying loading and caching classes.

Rushi
  • 4,553
  • 4
  • 33
  • 46
  • I tried this earlier, but doesn't work for me. I have already spend almost two days on it and that is more than enough. I am trying again so please guide me in this. –  Mar 28 '13 at 06:29
  • It is giving me following error: No visible @interface for uiimageview declares the selector 'loadImageFromURL:' at this line imgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 80, 90)]; [imgView loadImageFromURL:url]; [cell addSubview:imgView]; –  Mar 28 '13 at 06:47
  • I did your way it is overlapping images and shuffling the images on scrolling the table, do you have any solution for it. –  Mar 29 '13 at 04:09
  • @AppleDatasource Put autorelease in this line ASyncImage *img_EventImag = alloc with frame; – Rushi Mar 30 '13 at 04:58
  • Thanks but done already, please check the AsyncImageView.m file you provided is it compatible with code you provided. This method does not exist in that class. –  Mar 30 '13 at 05:46