iPhone 上实现异步加载图片并缓存代码




图片 1

- (void)viewDidLoad
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    [email protected]"EGOImageViewDemo";

    EGOImageView *imageView = [[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageNamed:@"1.jpg"]];
    imageView.imageURL = [NSURL URLWithString:@"http://f.dalang.gov.cn/uppic/2011-7-16/2011071610283352633.jpg"];
    imageView.frame = CGRectMake(10,100,100,100);
    [self.view addSubview:imageView];

图片 2




代码: – (void)viewDidLoad{ [super viewDidLoad]; // Do any additional
setup after loading the v…




//  AsyncImageView.h
//  Postcard
//  Created by markj on 2/18/09.
//  Copyright 2009 Mark Johnson. You have permission to copy parts of this code into your own projects for any use.
//  www.markj.net

#import <UIKit/UIKit.h>

@interface AsyncImageView : UIView {
    //could instead be a subclass of UIImageView instead of UIView, depending on what other features you want to 
    // to build into this class?

    NSURLConnection* connection; //keep a reference to the connection so we can cancel download in dealloc
    NSMutableData* data; //keep reference to the data so we can collect it as it downloads
    //but where is the UIImage reference? We keep it in self.subviews - no need to re-code what we have in the parent class


- (void)loadImageFromURL:(NSURL*)url;
- (UIImage*) image;



//  AsyncImageView.m
//  Postcard
//  Created by markj on 2/18/09.
//  Copyright 2009 Mark Johnson. You have permission to copy parts of this code into your own projects for any use.
//  www.markj.net

#import "AsyncImageView.h"

// This class demonstrates how the URL loading system can be used to make a UIView subclass
// that can download and display an image asynchronously so that the app doesn't block or freeze
// while the image is downloading. It works fine in a UITableView or other cases where there
// are multiple images being downloaded and displayed all at the same time. 

@implementation AsyncImageView

- (void)dealloc {
    [connection cancel]; //in case the URL is still downloading
    [connection release];
    [data release]; 
    [super dealloc];

- (void)loadImageFromURL:(NSURL*)url {
    if (connection!=nil) { [connection release]; } //in case we are downloading a 2nd image
    if (data!=nil) { [data release]; }

    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; //notice how delegate set to self object
    //TODO error handling, what if connection is nil?

//the URL connection calls this repeatedly as data arrives
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
    if (data==nil) { data = [[NSMutableData alloc] initWithCapacity:2048]; } 
    [data appendData:incrementalData];

//the URL connection calls this once all the data has downloaded
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
    //so self data now has the complete image 
    [connection release];
    if ([[self subviews] count]>0) {
        //then this must be another image, the old one is still in subviews
        [[[self subviews] objectAtIndex:0] removeFromSuperview]; //so remove it (releases it also)

    //make an image view for the image
    UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
    //make sizing choices based on your needs, experiment with these. maybe not all the calls below are needed.
    imageView.contentMode = UIViewContentModeScaleAspectFit;
    imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth || UIViewAutoresizingFlexibleHeight );
    [self addSubview:imageView];
    imageView.frame = self.bounds;
    [imageView setNeedsLayout];
    [self setNeedsLayout];

    [data release]; //don't need this any more, its in the UIImageView now

//just in case you want to get the image directly, here it is in subviews
- (UIImage*) image {
    UIImageView* iv = [[self subviews] objectAtIndex:0];
    return [iv image];



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

    static NSString *CellIdentifier = @"ImageCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc]
              initWithFrame:CGRectZero reuseIdentifier:CellIdentifier]
    } else {
    AsyncImageView* oldImage = (AsyncImageView*)
             [cell.contentView viewWithTag:999];
    [oldImage removeFromSuperview];

    CGRect frame;
    frame.size.width=75; frame.size.height=75;
    frame.origin.x=0; frame.origin.y=0;
    AsyncImageView* asyncImage = [[[AsyncImageView alloc]
               initWithFrame:frame] autorelease];
    asyncImage.tag = 999;
    NSURL* url = [imageDownload
    [asyncImage loadImageFromURL:url];

    [cell.contentView addSubview:asyncImage];

    return cell;


电子邮件地址不会被公开。 必填项已用*标注