UITableView 异步下载图片实例

先来看一下 效果图,有图有真相嘛

本文转自 http://www.999dh.net/article/iphone_ios_art/50.html 如转载,请注明!
在上面的地址中,有工程的下载链接,可以自由下载!
 
UITableView是可以用来显示图片的,如果图片的数量少,或者是已经集成在app里面的话,那这个处理起来很简单。但是如果图片需要从网上download下来,然后再显示的话,那耗时就比较厉害了。由于下载的速度比较慢,所以如果在主线程里面等待图片的下载并且更新的话,那界面体验非常差。
我这个例子是根据网上的一个名字叫WQTableViewController的例子修改的。在WQTableViewController的例子里面,用到了delete,经过我的修改,并没有用到 delegate,我不清楚为什么他们这么喜欢用delegate,因为我不用也可以实现啊,可能是我对delegate的理解还不够深刻。

WQTableViewController的例子有缺陷,那就是如果当前的cell还没有下载好图片,就算下载好之后,也需要滑动了才能显示,不滑动不显示,我把这个也修改了。

我的思路:先下载imagelist文件,里面存放了需要显示的文字,图片的url等信息。
imagelist文件只下载一次,这里不考虑更新的问题,下载后存放在cache里面,下次启动速度快
图片也是下载到cache里面的。我启动了2个主要的线程,第一个是下载全部图片的线程,第二个是下载当前可见cell对于的图片的线程,并且当前可见cell图片下载完一个就更新界面。这样就算不滑动界面也可以直接更新cell。

代码如下:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIScrollViewDelegate,UITableViewDelegate>
{
    NSMutableArray *tableDataArray;
}
@property (strong, nonatomic) IBOutlet UITableView *mytable;

@end


/////////////////////////////////////////////////

//
//  ViewController.m
//  lazyTableUpdate
//
//  Created by Rock 13-1-7.
//  Copyright (c) 2013年  All rights reserved.
//

#import "ViewController.h"
#import "SBJson.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize mytable;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Home", @"Home");
    }
    return self;
}

//下载所有的图片
-(void)downLoadAllImage
{
    NSInteger index = 0;
    
    for (index = 0; index < [tableDataArray count]; ++ index ) 
    {
        NSString *imageStr = [[[[tableDataArray objectAtIndex:index] valueForKey:@"im:image"] objectAtIndex:0] valueForKey:@"label"];
        
        NSString *imageName = [[[[tableDataArray objectAtIndex:index] valueForKey:@"im:name"] valueForKey:@"label"] stringByAppendingString:@".temp"];
        
        NSString *imageDataPath = [NSHomeDirectory() stringByAppendingPathComponent:[@"Library/Caches/" stringByAppendingString:imageName]];
        
        if (![[NSFileManager defaultManager] fileExistsAtPath:imageDataPath]) 
        {
            NSURL *imageUrl = [NSURL URLWithString:[imageStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
            NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
            [imageData writeToFile:imageDataPath atomically:YES];
        }
    }    
}


//下载当前可见cell的image
-(void)downLoadCurrentImage
{
    NSLog(@"downLoadCurrentImage");
    
    NSArray *indexPathsForLoad = [mytable indexPathsForVisibleRows];
    
    for (NSIndexPath *item in indexPathsForLoad) 
    {
        NSInteger rowNumberForCell = item.row;
        
        NSString *imageStr = [[[[tableDataArray objectAtIndex:rowNumberForCell] valueForKey:@"im:image"] objectAtIndex:0] valueForKey:@"label"];
        
        NSString *imageName = [[[[tableDataArray objectAtIndex:rowNumberForCell] valueForKey:@"im:name"] valueForKey:@"label"] stringByAppendingString:@".temp"];
        
        NSString *imageDataPath = [NSHomeDirectory() stringByAppendingPathComponent:[@"Library/Caches/" stringByAppendingString:imageName]];
        
        if (![[NSFileManager defaultManager] fileExistsAtPath:imageDataPath]) 
        {
            NSURL *imageUrl = [NSURL URLWithString:[imageStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
            NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
            [imageData writeToFile:imageDataPath atomically:YES];
            
            [self performSelectorOnMainThread:@selector(refreshUITableView:) withObject:nil waitUntilDone:YES];
        }
    }    
}

//刷新uitableview
-(void)refreshUITableView:(id)data
{
    [mytable reloadData];
}


-(void)StartThread
{
    [self performSelectorInBackground:@selector(downLoadCurrentImage) withObject:nil];
    [self performSelectorInBackground:@selector(downLoadAllImage) withObject:nil];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSString * filePath = [NSHomeDirectory() stringByAppendingPathComponent:[@"Library/Caches/" stringByAppendingString:@"image_lst.info"]];
    
    //只下载一次
    if(![[NSFileManager defaultManager] fileExistsAtPath:filePath])
    {
         NSString *jsonStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://phobos.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/toppaidapplications/limit=75/json"] encoding:NSUTF8StringEncoding error:nil];
        
        NSDictionary *dic = [jsonStr JSONValue];
        
        tableDataArray = [[dic valueForKey:@"feed"] valueForKey:@"entry"];
        
        NSData * data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
        [data writeToFile:filePath atomically:YES];
        
    }
    else 
    {
        NSLog(@"File Already Exists");
        
        NSString * jsonStr = [[NSString alloc]initWithData:[NSData dataWithContentsOfFile:filePath] encoding:NSUTF8StringEncoding];
        NSDictionary *dic = [jsonStr JSONValue];
        
        tableDataArray = [[dic valueForKey:@"feed"] valueForKey:@"entry"];
    }
    
    
    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(StartThread) userInfo:nil repeats:NO];
}

// customize the number of rows in the table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int count = [tableDataArray count];
    return count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"LazyTableCell";
    
    NSLog(@"cellForRowAtIndexPath");

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                       reuseIdentifier:CellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

    NSDictionary *item = [tableDataArray objectAtIndex:indexPath.row];
    
    cell.textLabel.text = [[item valueForKey:@"im:name"] valueForKey:@"label"];
    cell.detailTextLabel.text = [[item valueForKey:@"summary"] valueForKey:@"label"];
    
    NSString *imageName = [[[[tableDataArray objectAtIndex:indexPath.row] valueForKey:@"im:name"] valueForKey:@"label"] stringByAppendingString:@".temp"];
        
    NSString *imageDataPath = [NSHomeDirectory() stringByAppendingPathComponent:[@"Library/Caches/" stringByAppendingString:imageName]];
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imageDataPath]];
    
    if (image) 
    {
        cell.imageView.image = image;
    }
    else 
    {
        cell.imageView.image = [UIImage imageNamed:@"Placeholder.png"];//这个图片在工程里面是没有的  如果可以换成那种旋转的等待图片,那效果非常好
    }
    return cell;
}

//停止滚动之后启动下载当前cell图片的线程
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self performSelectorInBackground:@selector(downLoadCurrentImage) withObject:nil];
}

- (void)viewDidUnload
{
    [self setMytable:nil];
    mytable = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end
 

posted on 2013-01-08 09:54  景树园  阅读(242)  评论(0编辑  收藏  举报

导航