开发者

Loading images for multiple UITableView using lazy loading

开发者 https://www.devze.com 2023-01-07 23:00 出处:网络
I am developing an iPhone application with multiple table view. On each UITableview I have to load RSS feed data. Each feed has its own image.

I am developing an iPhone application with multiple table view. On each UITableview I have to load RSS feed data. Each feed has its own image.

For a singl开发者_开发百科e feed, I try to parse the xml and load the image inside the delegate itself.

Can any one advise me how to implement the lazy loading for all Rss feed view?


This sample project from Apple should help you make this happen.

http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Introduction/Intro.html


What i have created for a project of mine works as follows; Extend the UITableViewCell class by a category in "UITableViewCell+Async.h" (See some examples if you are not sure what the category thing in Obj C is)

@interface UITableViewCell (Async)

-(void)loadAsyncImage:(NSString*)url withIndex:(NSInteger)index inWidth:(NSInteger)width inHeight:(NSInteger)height;
-(void)loadAsyncBackground:(NSMutableArray*)parameters;

@end

And then in the implementation file "UITableViewCell+Async.m"

#import "UITableViewCell+Async.h"

@implementation UITableViewCell (Async)

-(void)loadAsyncImage:(NSString*)url 
            withIndex:(NSInteger)index 
              inWidth:(NSInteger)width 
             inHeight:(NSInteger)height {

    NSMutableArray* parameters = [NSMutableArray arrayWithCapacity:2];
    [parameters addObject:url];
    [parameters addObject:[NSNumber numberWithInteger:index]];
    [parameters addObject:[NSNumber numberWithInteger:width]];
    [parameters addObject:[NSNumber numberWithInteger:height]];

    self.imageView.tag = index;
    [self performSelectorInBackground:@selector(loadAsyncBackground:) withObject:parameters];

}

-(void)loadAsyncBackground:(NSMutableArray*)parameters {
    FootPrint
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString* url = [parameters objectAtIndex:0];
    NSInteger index = [[parameters objectAtIndex:1] integerValue];
    NSInteger width = [[parameters objectAtIndex:2] integerValue];
    NSInteger height = [[parameters objectAtIndex:3] integerValue];

    UIImage* image = [Utils getImageResized:url inSize:CGSizeMake(width, height)];

    if (self.tag==index) {
        self.imageView.image = image;
        [self setNeedsLayout];
    }

    [pool release];
}

@end

This basically adds a functionality to the UITableViewCell to load an image in a new background thread, resize the image and set it to the imageview. Checking the tag is added to see if the cell is still waiting for the image, since it can be re-used and another thread for the image could be downloading another image for that re-used cell...

The function in the above code with the signature of;

+(UIImage*)getImageResized:(NSString*)url inSize:(CGSize)size;

checks a local cache of images, downloads the image from the web if not in the cache, saves it to local cache, resizes the image in the given size and returns the image, all done in a sync(blocking) method call. Since this is already the background thread, no harm blocking it for this operation. When the method returns the image, it is set to the cell's imageview if it still has the same tag(not re-used for some other row)

In the cellForRowAtIndexPath method you can add the new category and you should be done;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"......."];
    if (cell == nil) {
................
    }
................
    [cell loadAsyncImage:deal.logo withIndex:indexPath.row inWidth:40 inHeight:40];
................

    return cell;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消