[z]使用NSoperation 实现异步加载图片

采用UITableView显示从网络上下载的图片,因为网络图片下载比较耗费时间,一般采用边显示文字,内容,后台下载图片,下载完成后刷新TableViewCell ,本文将演示如何通过自定的UITableViewCell,显示图片。

1。定义ImageTableViewCell 

@interface ImageTableViewCell : UITableViewCell {
    UILabel *txtLabel;
    UIImageView *imageView;
}
@property(nonatomic, retain)IBOutlet UILabel *txtLabel;
@property(nonatomic, retain)IBOutlet UIImageView *imageView;

- ( void)setCell:(UIImage *)image text:(NSString *)text;

@end 

方法添加如下 

 - (void)setCell:(UIImage *)image text:(NSString *)text

{
     if (image != nil)
    {
        self.imageView.image = image;
    }
    
    self.txtLabel.text = text;

}

 具体实现代码,请在源代码里查看

 

2。定义ImageDownloader ,这个类继承NSOperation,因为需要并发,所以需要实现下面4个方法 

//是否允许并发,
-(BOOL)isConcurrent 
- (BOOL)isExecuting
//是否已经完成,这个必须要重载,不然放在放在NSOperationQueue里的NSOpertaion不能正常释放。
- (BOOL)isFinished
//具体下载的方法在这里执行。

- (void)start 

 

而对应于非并发的情况下,只需要重载main方法就好了。

 

 

#import <Foundation/Foundation.h>

@protocol imageDownloaderDelegate;

@interface ImageDownloader : NSOperation 
{
    NSURLRequest* _request;
    
    NSURLConnection* _connection;
    
    NSMutableData* _data;
    
    BOOL _isFinished; 
    
     id<imageDownloaderDelegate>  delegate;
    
    NSObject *delPara;
}

- ( id)initWithURLString:(NSString *)url;

@property ( readonly) NSData *data;
@property(nonatomic, assign)  id<imageDownloaderDelegate>  delegate;
@property(nonatomic, retain) NSObject *delPara;

@end

@protocol imageDownloaderDelegate

@optional

// 图片下载完成的委托
- ( void)imageDidFinished:(UIImage *)image para:(NSObject *)obj;

@end

 

 

 实现文件如下

 #import "ImageDownloader.h"

@implementation ImageDownloader

@synthesize data=_data;
@synthesize  delegate;
@synthesize delPara;

- ( void)dealloc 
{
    
    [_request release]; 
    _request=nil;
    
    [_data release];
    _data=nil;
    
    [_connection release];
    _connection=nil;
    
    [delPara release];
    
    [super dealloc];
    
}
- ( id)initWithURLString:(NSString *)url 
{
    
    self = [self init];
     if (self) {

        _request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
        
        _data = [[NSMutableData data] retain];
        
    }
    
     return self;
    
}



//  开始处理-本类的主方法

- ( void)start {
    
     if (![self isCancelled]) {
        
        [NSThread sleepForTimeInterval: 3];
         //  以异步方式处理事件,并设置代理
        
        _connection=[[NSURLConnection connectionWithRequest:_request  delegate:self]retain];
        
         while(_connection != nil) {
            
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];   
            
        }
        
    }
    
}

#pragma mark NSURLConnection delegate Method

//  接收到数据(增量)时

- ( void)connection:(NSURLConnection*)connection

    didReceiveData:(NSData*)data 
{
     //  添加数据
    [_data appendData:data];
    
}

- ( void)connectionDidFinishLoading:(NSURLConnection*)connection {
    
    [_connection release],
    _connection=nil;
    NSLog( @" %s ", __func__);
    
    UIImage *img = [[[UIImage alloc] initWithData:self.data] autorelease];
    
     if (self. delegate != nil)
    {
        [ delegate imageDidFinished:img para:self.delPara];
    }
    
    
}

-( void)connection: (NSURLConnection *) connection didFailWithError: (NSError *) error
{
    [_connection release],
    _connection=nil; 
}

-(BOOL)isConcurrent 
{
     // 返回yes表示支持异步调用,否则为支持同步调用
     return YES;
    
}
- (BOOL)isExecuting
{
     return _connection == nil; 
}
- (BOOL)isFinished
{
     return _connection == nil;  
}


然后再UITableViewController里每个Cell创建的时候,如果没有图片的话,就通过ImageDownloader去下载,下载完了刷新这个Cell就可以了。

#import <UIKit/UIKit.h>
#import  " ImageDownloader.h "
@interface RootViewController : UITableViewController <imageDownloaderDelegate>
{
    NSOperationQueue *queue;
    NSMutableArray *siteArray;
    NSMutableArray *imageArray;
    NSMutableDictionary *dic;
}
@property(nonatomic, retain)NSOperationQueue *queue;
@property(nonatomic, retain)NSMutableArray *siteArray;
@property(nonatomic, retain)NSMutableArray *imageArray;

@end

 

 实现文件

 

//
//   RootViewController.m
//   NSOperationTest
//
//

#import  " RootViewController.h "
#import  " ImageDownloader.h "
#import  " ImageTableViewCell.h "

@implementation RootViewController
@synthesize queue;
@synthesize siteArray;
@synthesize imageArray;

- ( void)dealloc
{
    [self.queue release];
    [self.siteArray release];
    [self.imageArray release];
    [super dealloc];
}

- ( void)viewDidLoad
{
    [super viewDidLoad];
    self.queue = [[[NSOperationQueue alloc] init] autorelease];
    self.siteArray = [[[NSMutableArray alloc] init] autorelease];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg "];
    [self.siteArray addObject: @" http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg "];
    
    self.imageArray = [[[NSMutableArray alloc] init] autorelease];
     for (  int i =  0; i  < [self.siteArray count]; i++) 
    {
        [self.imageArray addObject: [NSNull  null]];
    }
    dic = [NSDictionary dictionary];
    
}

//  Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
     return  1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     return [siteArray count];
}

//  Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *CellIdentifier =  @" Cell ";
    
    ImageTableViewCell *cell = (ImageTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     if (cell == nil) 
    {
        NSArray *bundle = [[NSBundle mainBundle] loadNibNamed: @" ImageTableViewCell " owner:self options:nil];
        cell = (ImageTableViewCell *)[bundle objectAtIndex: 0];
    }

    NSString *text = [NSString stringWithFormat: @" %d ", indexPath.row];

    
    NSNull * null = (NSNull *)[self.imageArray objectAtIndex:indexPath.row];
    
     if (![ null isKindOfClass:[NSNull  class]])
    {
        [cell setCell:[imageArray objectAtIndex:indexPath.row] text:text];
  
    }
     else
    {
        [cell setCell:nil text:text];
        NSString *url = [self.siteArray objectAtIndex:indexPath.row];
        ImageDownloader *downloader = [[[ImageDownloader alloc] initWithURLString:url] autorelease];
        downloader. delegate = self;
        downloader.delPara = indexPath;
        [self.queue addOperation:downloader];
    }

     //  Configure the cell.
     return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
     return  112;
}




- ( void)imageDidFinished:(UIImage *)image para:(NSObject *)obj
{
    
    NSIndexPath *indexPath = (NSIndexPath *)obj;
    [self.imageArray replaceObjectAtIndex:indexPath.row withObject:image];
    ImageTableViewCell *cell = (ImageTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    NSString *text = [NSString stringWithFormat: @" %d ", indexPath.row];
    [cell setCell:image text:text];
    [cell setNeedsDisplay];

    
}

@end 

 

本文是通过委托实现的刷新Cell,你也可以通过一个Observer,观察图片是否下载完成,完成后就刷新图片所再Cell。通过Observer如何实现请参考这个网址http://blog.youkuaiyun.com/kmyhy/article/details/6050345 

 

本文地址:http://www.cnblogs.com/likwo/archive/2011/10/30/2229582.html

 

demo下载

转载于:https://www.cnblogs.com/aBigRoybot/archive/2011/11/25/2263168.html

多角色体系 支持管理员、商家、消费者三种角色,权限分级管控: 管理员:负责平台整体配置、用户审核、数据监控等全局操作。 商家:管理店铺信息、发布商品、处理订单、回复评价等。 消费者:浏览商品、加入购物车、下单支付、评价商品等。 实现用户注册(手机号 / 邮箱验证)、登录(支持密码 / 验证码 / 第三方登录)、个人信息管理(头像、收货地址、密码修改)。 权限精细化控制 商家仅能管理自家店铺及商品,消费者仅能查看和购买商品,管理员拥有全平台数据访问权限。 二、商品管理功能 商品信息维护 商家可发布商品:填写名称、分类(如服饰、电子产品)、子类别(如手机、笔记本)、规格(尺寸、颜色、型号)、价格、库存、详情描述(图文)、物流信息(运费、发货地)等。 支持商品上下架、库存调整、信息编辑,系统自动记录商品状态变更日志。 商品分类与搜索 按多级分类展示商品(如 “数码产品→手机→智能手机”),支持自定义分类体系。 提供智能搜索功能:按关键词(名称、品牌)搜索,支持模糊匹配和搜索联想;结合用户浏览历史对搜索结果排序(优先展示高相关度商品)。 商品推荐 基于用户浏览、收藏、购买记录,推荐相似商品(如 “浏览过该商品的用户还买了…”)。 首页展示热门商品(销量 TOP10)、新品上架、限时折扣等推荐列表。 三、订单与交易管理 购物车与下单 消费者可将商品加入购物车,支持修改数量、选择规格、移除商品,系统自动计算总价(含运费、折扣)。 下单流程:确认收货地址→选择支付方式(在线支付、货到付款)→提交订单→系统生成唯一订单号。 订单处理流程 订单状态跟踪:待支付→已支付→商家发货→物流运输→消费者收货→订单完成,各状态变更实时通知用户。 商家端功能:查看新订单提醒、确认发货(填写物流单号)、处理退款申请(需审核理由)。 消费者端功能:查看订单详情、追踪物流、申请退款 / 退货、确认收货。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值